keepalived-0.5.5 v0.5.5
authorAlexandre Cassen <acassen@freebox.fr>
Tue, 9 Apr 2002 23:49:46 +0000 (01:49 +0200)
committerAlexandre Cassen <acassen@freebox.fr>
Mon, 28 Sep 2009 08:58:54 +0000 (10:58 +0200)
* keepalived-0.5.5 released.
* Fixed a gratuitous ARP porting bug.
* VRRP : Review the data structure to be more generic
  and clean with the rest of the code.
* VRRP : Remove the interface flags (NIC) ioctl functions
* VRRP : Created an interface (NIC) library giving access
  to common interface helpers functions.
* VRRP : Created an interface lookup function creating a global
  interface structure during daemon bootstrap. Consist of a netlink
  RTM_GETLINK & RTM_GETADDR lookup, so we can work with a userspace
  interface representation.
* VRRP : Create a netlink kernel reflection framework updating
  dynamically our interface structure according to kernel
  netlink broadcast. This design is highly inspired from zebra.
  => Reflection mean : wait for netlink kernel broadcast, if received,
  wakeup netlink filter to update our userspace representation.
  Prefer this design instead of a delayed netlink poller. That way
  we reduce global overhead.
* VRRP : VRRP need to detect failure from many places.
  If netlink can notify for many troubles like mainly
  IFF_UP|DOWN & IFF_RUNNING, those flags are kernel drivers dependent.
  To reduce takeover time and performance we need to have informations like
  : Does the media link is present ?. The fact is that most of the new NICs
  own embended hardware chip providing such informations. So created a
  MII transceiver status register thread poller. Monitoring Basic Mode
  Status Register (BMSR) of the MII status words. Waiting for kernel
  NIC drivers hackers to support this functionnality through netlink
  (=> Like a IFF_RUNNING update broadcast).
* VRRP : Linked the state machine to the global interface structure.
  NIC failure/events are handled.
* VRRP : Review the whole state machine code to be more realistic. The
  State transition diagram described into the RFC2338 is an obtimist
  view. The VRRP state transition diagram implemented here is :
                      +---------------+
           +--------->|               |<-------------+
           |          |  Initialize   |              |
           |   +------|               |----------+   |
           |   |      +---------------+          |   |
           |   V                                 V   |
   +---------------+                       +---------------+
   |               |---------------------->|               |
   |    Master     |                       |    Backup     |
   |               |<----------------------|               |
   +---------------+                       +---------------+
    ^   |     |                                   |    ^
    |   |     |       +---------------+           |    |
    |   |     +------>|  Dummy Master |           |    |
    |   |             +---------------+           |    |
    |   |                     |                   |    |
    |   |                     V                   |    |
    |   |             +---------------+           |    |
    |   +------------>|               |<----------+    |
    |                 |     Fault     |                |
    +-----------------|               |----------------+
                      +---------------+
* VRRP : Robust multicast handling. Something really strange
  is : after a NIC failure (in fallback mode) without closing
  the socket, multicast advert can be sent but not received ?
  really strange don t know why probably an IGMP resubmit ?.
  So multicast group is left during failover (media trouble,
  IFF_DOWN or !IFF_RUNNING). In fallback, we register a new
  membership and synchronize all the packet dispatcher fds.
* VRRP : Fixed a checksum trouble using password authentication.
* VRRP : Added support to the LVS sync daemon. This permit
  LVS sync daemon to be state drived by a specific VRRP instance.
* Review the autoconf/automake to be more generic.
* Some cosmetics patches.

73 files changed:
.data.c.swp [deleted file]
CONTRIBUTORS
ChangeLog
Makefile.in
VERSION
check_api.c
check_api.h
check_http.c
check_http.h
check_misc.c
check_misc.h
check_ssl.c
check_ssl.h
check_tcp.c
check_tcp.h
configure
configure.in
daemon.c
daemon.h
data.c
data.h
etc/keepalived/keepalived.conf
genhash/Makefile [new file with mode: 0644]
genhash/main.h
ipfwwrapper.c
ipfwwrapper.h
ipvswrapper.c
ipvswrapper.h
ipwrapper.c
ipwrapper.h
layer4.c
layer4.h
libipfwc/Makefile
libipfwc/libipfwc.c
list.c
list.h
main.c
main.h
memory.c
memory.h
parser.c
parser.h
pidfile.c
pidfile.h
samples/keepalived.conf.SSL_GET
samples/keepalived.conf.misc_check
samples/keepalived.conf.sample
samples/keepalived.conf.ssl
samples/keepalived.conf.vrrp
samples/keepalived.conf.vrrp.lvs_syncd [new file with mode: 0644]
samples/keepalived.conf.vrrp.sync
scheduler.c
scheduler.h
smtp.c
smtp.h
timer.c
timer.h
utils.c
utils.h
vector.c
vector.h
vrrp.c
vrrp.h
vrrp_if.c [new file with mode: 0644]
vrrp_if.h [new file with mode: 0644]
vrrp_ipaddress.c
vrrp_ipaddress.h
vrrp_ipsecah.c
vrrp_ipsecah.h
vrrp_netlink.c
vrrp_netlink.h
vrrp_scheduler.c
vrrp_scheduler.h

diff --git a/.data.c.swp b/.data.c.swp
deleted file mode 100644 (file)
index 1602318..0000000
Binary files a/.data.c.swp and /dev/null differ
index 29a5aba..801a6bb 100644 (file)
@@ -1 +1 @@
-Jan Holmberg <jan@artech.net>
+Jan Holmberg, <jan@artech.net>
index 269b548..7f819d7 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,74 @@
+2002-04-10  Alexandre Cassen  <acassen@linux-vs.org>
+       * keepalived-0.5.5 released.
+       * Fixed a gratuitous ARP porting bug.
+       * VRRP : Review the data structure to be more generic
+         and clean with the rest of the code.
+       * VRRP : Remove the interface flags (NIC) ioctl functions
+       * VRRP : Created an interface (NIC) library giving access
+         to common interface helpers functions.
+       * VRRP : Created an interface lookup function creating a global
+         interface structure during daemon bootstrap. Consist of a netlink
+         RTM_GETLINK & RTM_GETADDR lookup, so we can work with a userspace
+         interface representation.
+       * VRRP : Create a netlink kernel reflection framework updating
+         dynamically our interface structure according to kernel
+         netlink broadcast. This design is highly inspired from zebra.
+         => Reflection mean : wait for netlink kernel broadcast, if received,
+         wakeup netlink filter to update our userspace representation.
+         Prefer this design instead of a delayed netlink poller. That way
+         we reduce global overhead.
+       * VRRP : VRRP need to detect failure from many places.
+         If netlink can notify for many troubles like mainly
+         IFF_UP|DOWN & IFF_RUNNING, those flags are kernel drivers dependent.
+         To reduce takeover time and performance we need to have informations like
+         : Does the media link is present ?. The fact is that most of the new NICs
+         own embended hardware chip providing such informations. So created a
+         MII transceiver status register thread poller. Monitoring Basic Mode
+         Status Register (BMSR) of the MII status words. Waiting for kernel
+         NIC drivers hackers to support this functionnality through netlink
+          (=> Like a IFF_RUNNING update broadcast).
+       * VRRP : Linked the state machine to the global interface structure.
+         NIC failure/events are handled.
+       * VRRP : Review the whole state machine code to be more realistic. The
+         State transition diagram described into the RFC2338 is an obtimist
+         view. The VRRP state transition diagram implemented here is :
+
+                              +---------------+
+                   +--------->|               |<-------------+
+                   |          |  Initialize   |              |
+                   |   +------|               |----------+   |
+                   |   |      +---------------+          |   |
+                   |   V                                 V   |
+           +---------------+                       +---------------+
+           |               |---------------------->|               |
+           |    Master     |                       |    Backup     |
+           |               |<----------------------|               |
+           +---------------+                       +---------------+
+            ^   |     |                                   |    ^
+            |   |     |       +---------------+           |    |
+            |   |     +------>|  Dummy Master |           |    |
+            |   |             +---------------+           |    |
+            |   |                     |                   |    |
+            |   |                     V                   |    |
+            |   |             +---------------+           |    |
+            |   +------------>|               |<----------+    |
+            |                 |     Fault     |                |
+            +-----------------|               |----------------+
+                              +---------------+
+
+       * VRRP : Robust multicast handling. Something really strange
+         is : after a NIC failure (in fallback mode) without closing
+         the socket, multicast advert can be sent but not received ?
+         really strange don t know why probably an IGMP resubmit ?.
+         So multicast group is left during failover (media trouble,
+          IFF_DOWN or !IFF_RUNNING). In fallback, we register a new
+         membership and synchronize all the packet dispatcher fds.
+       * VRRP : Fixed a checksum trouble using password authentication.
+       * VRRP : Added support to the LVS sync daemon. This permit
+         LVS sync daemon to be state drived by a specific VRRP instance.
+       * Review the autoconf/automake to be more generic.
+       * Some cosmetics patches.
+
 2002-02-25  Alexandre Cassen  <acassen@linux-vs.org>
        * keepalived-0.5.3 released.
        * Added autoconf / automake generic scripts.
index afe5e41..325ad9f 100644 (file)
@@ -19,7 +19,7 @@ keepalived_conf_dir = /etc/keepalived
 
 CC = @CC@
 CFLAGS = @CFLAGS@ -Wall -Wunused -Wstrict-prototypes -D_DEBUG_ -D$(KERNEL)
-LDFLAGS = @LIBS@ @LDFLAGS@
+LDFLAGS = @LIBS@ @LDFLAGS@ @LIBFW@
 OBJS = @LIBOBJS@ \
        main.o \
        memory.o \
@@ -44,6 +44,7 @@ OBJS = @LIBOBJS@ \
        vrrp.o \
        vrrp_scheduler.o \
        vrrp_netlink.o \
+       vrrp_if.o \
        vrrp_ipaddress.o \
        vrrp_ipsecah.o
 
diff --git a/VERSION b/VERSION
index be14282..d1d899f 100644 (file)
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-0.5.3
+0.5.5
index d7973aa..a742fe4 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Part:        Checkers registration.
  *
- * Version:     $Id: check_api.c,v 0.5.3 2002/02/24 23:50:11 acassen Exp $
+ * Version:     $Id: check_api.c,v 0.5.5 2002/04/10 02:34:23 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
@@ -23,6 +23,7 @@
 #include "check_api.h"
 #include "parser.h"
 #include "memory.h"
+#include "utils.h"
 #include "check_misc.h"
 #include "check_tcp.h"
 #include "check_http.h"
index 391f99d..4636457 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Part:        Checkers arguments structures definitions.
  *
- * Version:     $Id: check_api.h,v 0.5.3 2002/02/24 23:50:11 acassen Exp $
+ * Version:     $Id: check_api.h,v 0.5.5 2002/04/10 02:34:23 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
index 0216f8a..778daef 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Part:        WEB CHECK. Common HTTP/SSL checker primitives.
  *
- * Version:     $Id: check_http.c,v 0.5.3 2002/02/24 23:50:11 acassen Exp $
+ * Version:     $Id: check_http.c,v 0.5.5 2002/04/10 02:34:23 acassen Exp $
  *
  * Authors:     Alexandre Cassen, <acassen@linux-vs.org>
  *              Jan Holmberg, <jan@artech.net>
index 34ae5c2..97ecb81 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Part:        check_http.c include file.
  *
- * Version:     $Id: check_http.h,v 0.5.3 2002/02/24 23:50:11 acassen Exp $
+ * Version:     $Id: check_http.h,v 0.5.5 2002/04/10 02:34:23 acassen Exp $
  *
  * Authors:     Alexandre Cassen, <acassen@linux-vs.org>
  *              Jan Holmberg, <jan@artech.net>
index c13ca46..779b083 100644 (file)
@@ -6,7 +6,7 @@
  * Part:        MISC CHECK. Perform a system call to run an extra
  *              system prog or script.
  *
- * Version:     $Id: check_misc.c,v 0.5.3 2002/02/24 23:50:11 acassen Exp $
+ * Version:     $Id: check_misc.c,v 0.5.5 2002/04/10 02:34:23 acassen Exp $
  *
  * Authors:     Alexandre Cassen, <acassen@linux-vs.org>
  *              Eric Jarman, <ehj38230@cmsu2.cmsu.edu>
index 3ed9970..f149d98 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Part:        check_misc.c include file.
  *
- * Version:     $Id: check_misc.h,v 0.5.3 2002/02/24 23:50:11 acassen Exp $
+ * Version:     $Id: check_misc.h,v 0.5.5 2002/04/10 02:34:23 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *              Eric Jarman, <ehj38230@cmsu2.cmsu.edu>
index c0812c1..4872b02 100644 (file)
@@ -7,7 +7,7 @@
  *              url, compute a MD5 over this result and match it to the
  *              expected value.
  *
- * Version:     $Id: check_ssl.c,v 0.5.3 2002/02/24 23:50:11 acassen Exp $
+ * Version:     $Id: check_ssl.c,v 0.5.5 2002/04/10 02:34:23 acassen Exp $
  *
  * Authors:     Alexandre Cassen, <acassen@linux-vs.org>
  *              Jan Holmberg, <jan@artech.net>
index d302fe3..40eacb4 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Part:        check_http.c include file.
  *
- * Version:     $Id: check_http.h,v 0.5.3 2002/02/24 23:50:11 acassen Exp $
+ * Version:     $Id: check_http.h,v 0.5.5 2002/04/10 02:34:23 acassen Exp $
  *
  * Authors:     Alexandre Cassen, <acassen@linux-vs.org>
  *              Jan Holmberg, <jan@artech.net>
index f97521a..db5cfba 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Part:        TCP checker.
  *
- * Version:     $Id: check_tcp.c,v 0.5.3 2002/02/24 23:50:11 acassen Exp $
+ * Version:     $Id: check_tcp.c,v 0.5.5 2002/04/10 02:34:23 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
index 2a251c0..0504d5a 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Part:        check_tcp.c include file.
  *
- * Version:     $Id: check_tcp.h,v 0.5.3 2002/02/24 23:50:11 acassen Exp $
+ * Version:     $Id: check_tcp.h,v 0.5.5 2002/04/10 02:34:23 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
index 20b219e..50f6ad9 100755 (executable)
--- a/configure
+++ b/configure
@@ -451,7 +451,7 @@ echo > confdefs.h
 
 # A filename unique to this package, relative to the directory that
 # configure is in, which we can look for to find out if srcdir is correct.
-ac_unique_file=parser.c
+ac_unique_file=scheduler.c
 
 # Find the source files, if location was not specified.
 if test -z "$srcdir"; then
@@ -829,9 +829,16 @@ test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
 
 
 KERNEL_VERSION=`uname -r`
-modprobe ip_vs
+
+IPVS_MODULE="/lib/modules/`uname -r`/kernel/net/ipv4/ipvs/ip_vs.o"
+if test -f $IPVS_MODULE; then
+  modprobe ip_vs
+fi
+
 if test -f /proc/net/ip_vs; then
   IPVS_VERSION=`cat /proc/net/ip_vs | head -1 | awk '{ print $5}'`
+elif test -f /proc/net/ip_masq/vs; then
+  IPVS_VERSION=`cat /proc/net/ip_masq/vs | head -1 | awk '{ print $5}'`
 else
   echo
   echo "!!!WARN!!! Your kernel need to be patched with LVS code !!!WARN!!!"
@@ -840,23 +847,27 @@ else
 fi
 VERSION=`cat VERSION`
 
-echo $ac_n "checking for main in -lcrypto""... $ac_c" 1>&6
-echo "configure:845: checking for main in -lcrypto" >&5
-ac_lib_var=`echo crypto'_'main | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for MD5_Init in -lcrypto""... $ac_c" 1>&6
+echo "configure:852: 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
 else
   ac_save_LIBS="$LIBS"
 LIBS="-lcrypto  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 853 "configure"
+#line 860 "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 MD5_Init();
 
 int main() {
-main()
+MD5_Init()
 ; return 0; }
 EOF
-if { (eval echo configure:860: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:871: \"$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
@@ -881,25 +892,30 @@ EOF
 
 else
   echo "$ac_t""no" 1>&6
+{ echo "configure: error: OpenSSL libraries are required" 1>&2; exit 1; }
 fi
 
-echo $ac_n "checking for main in -lpopt""... $ac_c" 1>&6
-echo "configure:888: checking for main in -lpopt" >&5
-ac_lib_var=`echo popt'_'main | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for SSL_CTX_new in -lssl""... $ac_c" 1>&6
+echo "configure:900: 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
 else
   ac_save_LIBS="$LIBS"
-LIBS="-lpopt  $LIBS"
+LIBS="-lssl  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 896 "configure"
+#line 908 "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 SSL_CTX_new();
 
 int main() {
-main()
+SSL_CTX_new()
 ; return 0; }
 EOF
-if { (eval echo configure:903: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:919: \"$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
@@ -914,35 +930,40 @@ 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 popt | sed -e 's/[^a-zA-Z0-9_]/_/g' \
+    ac_tr_lib=HAVE_LIB`echo ssl | sed -e 's/[^a-zA-Z0-9_]/_/g' \
     -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'`
   cat >> confdefs.h <<EOF
 #define $ac_tr_lib 1
 EOF
 
-  LIBS="-lpopt $LIBS"
+  LIBS="-lssl $LIBS"
 
 else
   echo "$ac_t""no" 1>&6
+{ echo "configure: error: OpenSSL libraries are required" 1>&2; exit 1; }
 fi
 
-echo $ac_n "checking for main in -lssl""... $ac_c" 1>&6
-echo "configure:931: checking for main in -lssl" >&5
-ac_lib_var=`echo ssl'_'main | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for poptGetContext in -lpopt""... $ac_c" 1>&6
+echo "configure:948: 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
 else
   ac_save_LIBS="$LIBS"
-LIBS="-lssl  $LIBS"
+LIBS="-lpopt  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 939 "configure"
+#line 956 "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 poptGetContext();
 
 int main() {
-main()
+poptGetContext()
 ; return 0; }
 EOF
-if { (eval echo configure:946: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:967: \"$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
@@ -957,27 +978,28 @@ 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 ssl | sed -e 's/[^a-zA-Z0-9_]/_/g' \
+    ac_tr_lib=HAVE_LIB`echo popt | sed -e 's/[^a-zA-Z0-9_]/_/g' \
     -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'`
   cat >> confdefs.h <<EOF
 #define $ac_tr_lib 1
 EOF
 
-  LIBS="-lssl $LIBS"
+  LIBS="-lpopt $LIBS"
 
 else
   echo "$ac_t""no" 1>&6
+{ echo "configure: error: Popt libraries is required" 1>&2; exit 1; }
 fi
 
 
 KERNEL_CODE=`echo $KERNEL_VERSION | cut -d'.' -f2`
 if test "${KERNEL_CODE}" = "2"; then
-  LDFLAGS = ${LIBS} libipfwc/libipfwc.a
-  LIBOBJS = ${LIBOBJS} ipfwwrapper.o
-fi
+  LIBFW="libipfwc/libipfwc.a"
+  LIBOBJS="$LIBOBJS ipfwwrapper.o"
+    fi
 
 echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6
-echo "configure:981: checking how to run the C preprocessor" >&5
+echo "configure:1003: checking how to run the C preprocessor" >&5
 # On Suns, sometimes $CPP names a directory.
 if test -n "$CPP" && test -d "$CPP"; then
   CPP=
@@ -992,13 +1014,13 @@ else
   # On the NeXT, cc -E runs the code through the compiler's parser,
   # not just through cpp.
   cat > conftest.$ac_ext <<EOF
-#line 996 "configure"
+#line 1018 "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:1002: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:1024: \"$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
   :
@@ -1009,13 +1031,13 @@ else
   rm -rf conftest*
   CPP="${CC-cc} -E -traditional-cpp"
   cat > conftest.$ac_ext <<EOF
-#line 1013 "configure"
+#line 1035 "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:1019: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:1041: \"$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
   :
@@ -1026,13 +1048,13 @@ else
   rm -rf conftest*
   CPP="${CC-cc} -nologo -E"
   cat > conftest.$ac_ext <<EOF
-#line 1030 "configure"
+#line 1052 "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:1036: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:1058: \"$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
   :
@@ -1057,12 +1079,12 @@ fi
 echo "$ac_t""$CPP" 1>&6
 
 echo $ac_n "checking for ANSI C header files""... $ac_c" 1>&6
-echo "configure:1061: checking for ANSI C header files" >&5
+echo "configure:1083: 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 1066 "configure"
+#line 1088 "configure"
 #include "confdefs.h"
 #include <stdlib.h>
 #include <stdarg.h>
@@ -1070,7 +1092,7 @@ else
 #include <float.h>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:1074: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:1096: \"$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*
@@ -1087,7 +1109,7 @@ rm -f 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 1091 "configure"
+#line 1113 "configure"
 #include "confdefs.h"
 #include <string.h>
 EOF
@@ -1105,7 +1127,7 @@ fi
 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 1109 "configure"
+#line 1131 "configure"
 #include "confdefs.h"
 #include <stdlib.h>
 EOF
@@ -1126,7 +1148,7 @@ if test "$cross_compiling" = yes; then
   :
 else
   cat > conftest.$ac_ext <<EOF
-#line 1130 "configure"
+#line 1152 "configure"
 #include "confdefs.h"
 #include <ctype.h>
 #define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
@@ -1137,7 +1159,7 @@ if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) exit(2);
 exit (0); }
 
 EOF
-if { (eval echo configure:1141: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:1163: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
 then
   :
 else
@@ -1161,12 +1183,12 @@ EOF
 fi
 
 echo $ac_n "checking for sys/wait.h that is POSIX.1 compatible""... $ac_c" 1>&6
-echo "configure:1165: checking for sys/wait.h that is POSIX.1 compatible" >&5
+echo "configure:1187: 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 1170 "configure"
+#line 1192 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #include <sys/wait.h>
@@ -1182,7 +1204,7 @@ wait (&s);
 s = WIFEXITED (s) ? WEXITSTATUS (s) : 1;
 ; return 0; }
 EOF
-if { (eval echo configure:1186: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:1208: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   ac_cv_header_sys_wait_h=yes
 else
@@ -1202,21 +1224,64 @@ EOF
 
 fi
 
+for ac_hdr in openssl/ssl.h openssl/md5.h openssl/err.h
+do
+ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
+echo "configure:1232: 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 1237 "configure"
+#include "confdefs.h"
+#include <$ac_hdr>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:1242: \"$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
+{ echo "configure: error: 
+  !!! OpenSSL is not properly installed on your system. !!!
+  !!! Can not include OpenSSL headers files.            !!!" 1>&2; exit 1; }
+fi
+done
+
 for ac_hdr in fcntl.h sys/ioctl.h sys/time.h syslog.h unistd.h
 do
 ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
 echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
-echo "configure:1210: checking for $ac_hdr" >&5
+echo "configure:1275: 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 1215 "configure"
+#line 1280 "configure"
 #include "confdefs.h"
 #include <$ac_hdr>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:1220: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:1285: \"$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*
@@ -1244,12 +1309,12 @@ done
 
 
 echo $ac_n "checking for working const""... $ac_c" 1>&6
-echo "configure:1248: checking for working const" >&5
+echo "configure:1313: 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 1253 "configure"
+#line 1318 "configure"
 #include "confdefs.h"
 
 int main() {
@@ -1298,7 +1363,7 @@ ccp = (char const *const *) p;
 
 ; return 0; }
 EOF
-if { (eval echo configure:1302: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:1367: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   ac_cv_c_const=yes
 else
@@ -1319,12 +1384,12 @@ EOF
 fi
 
 echo $ac_n "checking for pid_t""... $ac_c" 1>&6
-echo "configure:1323: checking for pid_t" >&5
+echo "configure:1388: 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 1328 "configure"
+#line 1393 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #if STDC_HEADERS
@@ -1352,12 +1417,12 @@ EOF
 fi
 
 echo $ac_n "checking whether time.h and sys/time.h may both be included""... $ac_c" 1>&6
-echo "configure:1356: checking whether time.h and sys/time.h may both be included" >&5
+echo "configure:1421: 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 1361 "configure"
+#line 1426 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #include <sys/time.h>
@@ -1366,7 +1431,7 @@ int main() {
 struct tm *tp;
 ; return 0; }
 EOF
-if { (eval echo configure:1370: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:1435: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   ac_cv_header_time=yes
 else
@@ -1389,13 +1454,13 @@ fi
 
 if test $ac_cv_prog_gcc = yes; then
     echo $ac_n "checking whether ${CC-cc} needs -traditional""... $ac_c" 1>&6
-echo "configure:1393: checking whether ${CC-cc} needs -traditional" >&5
+echo "configure:1458: 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 1399 "configure"
+#line 1464 "configure"
 #include "confdefs.h"
 #include <sgtty.h>
 Autoconf TIOCGETP
@@ -1413,7 +1478,7 @@ rm -f conftest*
 
   if test $ac_cv_prog_gcc_traditional = no; then
     cat > conftest.$ac_ext <<EOF
-#line 1417 "configure"
+#line 1482 "configure"
 #include "confdefs.h"
 #include <termio.h>
 Autoconf TCGETA
@@ -1434,49 +1499,13 @@ echo "$ac_t""$ac_cv_prog_gcc_traditional" 1>&6
   fi
 fi
 
-echo $ac_n "checking for 8-bit clean memcmp""... $ac_c" 1>&6
-echo "configure:1439: checking for 8-bit clean memcmp" >&5
-if eval "test \"`echo '$''{'ac_cv_func_memcmp_clean'+set}'`\" = set"; then
-  echo $ac_n "(cached) $ac_c" 1>&6
-else
-  if test "$cross_compiling" = yes; then
-  ac_cv_func_memcmp_clean=no
-else
-  cat > conftest.$ac_ext <<EOF
-#line 1447 "configure"
-#include "confdefs.h"
-
-main()
-{
-  char c0 = 0x40, c1 = 0x80, c2 = 0x81;
-  exit(memcmp(&c0, &c2, 1) < 0 && memcmp(&c1, &c2, 1) < 0 ? 0 : 1);
-}
-
-EOF
-if { (eval echo configure:1457: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
-then
-  ac_cv_func_memcmp_clean=yes
-else
-  echo "configure: failed program was:" >&5
-  cat conftest.$ac_ext >&5
-  rm -fr conftest*
-  ac_cv_func_memcmp_clean=no
-fi
-rm -fr conftest*
-fi
-
-fi
-
-echo "$ac_t""$ac_cv_func_memcmp_clean" 1>&6
-test $ac_cv_func_memcmp_clean = no && LIBOBJS="$LIBOBJS memcmp.${ac_objext}"
-
 echo $ac_n "checking return type of signal handlers""... $ac_c" 1>&6
-echo "configure:1475: checking return type of signal handlers" >&5
+echo "configure:1504: 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 1480 "configure"
+#line 1509 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #include <signal.h>
@@ -1493,7 +1522,7 @@ int main() {
 int i;
 ; return 0; }
 EOF
-if { (eval echo configure:1497: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:1526: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   ac_cv_type_signal=void
 else
@@ -1514,12 +1543,12 @@ EOF
 for ac_func in gettimeofday select socket strerror strtol uname
 do
 echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:1518: checking for $ac_func" >&5
+echo "configure:1547: 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 1523 "configure"
+#line 1552 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char $ac_func(); below.  */
@@ -1542,7 +1571,7 @@ $ac_func();
 
 ; return 0; }
 EOF
-if { (eval echo configure:1546: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:1575: \"$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
@@ -1716,8 +1745,9 @@ s%@CC@%$CC%g
 s%@INSTALL_PROGRAM@%$INSTALL_PROGRAM%g
 s%@INSTALL_SCRIPT@%$INSTALL_SCRIPT%g
 s%@INSTALL_DATA@%$INSTALL_DATA%g
-s%@CPP@%$CPP%g
+s%@LIBFW@%$LIBFW%g
 s%@LIBOBJS@%$LIBOBJS%g
+s%@CPP@%$CPP%g
 
 CEOF
 EOF
@@ -1840,5 +1870,8 @@ Linux Kernel release : ${KERNEL_VERSION}
 IPVS version code    : ${IPVS_VERSION}
 Compiler             : ${CC}
 Compiler flags       : ${CFLAGS}
+Extra Lib            : $LIBS
+Lib objects          : $LIBOBJS
+Firewall Lib         : $LIBFW
 
 EOF
index 3cbcc73..d1cb12d 100644 (file)
@@ -7,7 +7,7 @@
 # Copyright (C) 2001, 2002 Alexandre Cassen, <acassen@linux-vs.org>
 
 dnl ----[ Process this file with autoconf to produce a configure script ]----
-AC_INIT(cfreader.c)
+AC_INIT(scheduler.c)
 
 dnl ----[ Checks for programs ]----
 AC_PROG_CC
@@ -15,9 +15,16 @@ AC_PROG_INSTALL
 
 dnl ----[ Checks for kernel support ]----
 KERNEL_VERSION=`uname -r`
-modprobe ip_vs
+
+IPVS_MODULE="/lib/modules/`uname -r`/kernel/net/ipv4/ipvs/ip_vs.o"
+if test -f $IPVS_MODULE; then
+  modprobe ip_vs
+fi
+
 if test -f /proc/net/ip_vs; then
   IPVS_VERSION=`cat /proc/net/ip_vs | head -1 | awk '{ print $5}'`
+elif test -f /proc/net/ip_masq/vs; then
+  IPVS_VERSION=`cat /proc/net/ip_masq/vs | head -1 | awk '{ print $5}'`
 else
   echo
   echo "!!!WARN!!! Your kernel need to be patched with LVS code !!!WARN!!!"
@@ -27,23 +34,25 @@ fi
 VERSION=`cat VERSION`
 
 dnl ----[ Checks for libraries ]----
-dnl Replace `main' with a function in -lcrypto:
-AC_CHECK_LIB(crypto, main)
-dnl Replace `main' with a function in -lpopt:
-AC_CHECK_LIB(popt, main)
-dnl Replace `main' with a function in -lssl:
-AC_CHECK_LIB(ssl, main)
+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]))
 
 dnl ----[ Create object list ]----
 KERNEL_CODE=`echo $KERNEL_VERSION | cut -d'.' -f2`
 if test "${KERNEL_CODE}" = "2"; then
-  LDFLAGS = ${LIBS} libipfwc/libipfwc.a
-  LIBOBJS = ${LIBOBJS} ipfwwrapper.o
+  LIBFW="libipfwc/libipfwc.a"
+  LIBOBJS="$LIBOBJS ipfwwrapper.o"
+  AC_SUBST(LIBFW)dnl
+  AC_SUBST(LIBOBJS)dnl
 fi
 
 dnl ----[ Checks for header files ]----
 AC_HEADER_STDC
 AC_HEADER_SYS_WAIT
+AC_CHECK_HEADERS(openssl/ssl.h openssl/md5.h openssl/err.h,,AC_MSG_ERROR([
+  !!! 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)
 
 dnl ----[ Checks for typedefs, structures, and compiler characteristics ]----
@@ -53,7 +62,7 @@ AC_HEADER_TIME
 
 dnl ----[ Checks for library functions ]----
 AC_PROG_GCC_TRADITIONAL
-AC_FUNC_MEMCMP
+dnl AC_FUNC_MEMCMP
 AC_TYPE_SIGNAL
 AC_CHECK_FUNCS(gettimeofday select socket strerror strtol uname)
 
@@ -68,5 +77,8 @@ Linux Kernel release : ${KERNEL_VERSION}
 IPVS version code    : ${IPVS_VERSION}
 Compiler             : ${CC}
 Compiler flags       : ${CFLAGS}
+Extra Lib            : $LIBS
+Lib objects          : $LIBOBJS
+Firewall Lib         : $LIBFW
 
 EOF
index f0a4b69..498a254 100644 (file)
--- a/daemon.c
+++ b/daemon.c
@@ -5,7 +5,7 @@
  *
  * Part:        Main program structure.
  *
- * Version:     $Id: main.c,v 0.5.3 2002/02/24 23:50:11 acassen Exp $
+ * Version:     $Id: main.c,v 0.5.5 2002/04/10 02:34:23 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
index 719c327..9ceb279 100644 (file)
--- a/daemon.h
+++ b/daemon.h
@@ -5,7 +5,7 @@
  *
  * Part:        Daemon process handling.
  *
- * Version:     $Id: daemon.h,v 0.5.3 2002/02/24 23:50:11 acassen Exp $
+ * Version:     $Id: daemon.h,v 0.5.5 2002/04/10 02:34:23 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
diff --git a/data.c b/data.c
index a01abb0..0e95c51 100644 (file)
--- a/data.c
+++ b/data.c
@@ -5,7 +5,7 @@
  *
  * Part:        Dynamic data structure definition.
  *
- * Version:     $Id: data.c,v 0.5.3 2002/02/24 23:50:11 acassen Exp $
+ * Version:     $Id: data.c,v 0.5.5 2002/04/10 02:34:23 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
@@ -24,6 +24,7 @@
 #include "memory.h"
 #include "utils.h"
 #include "check_api.h"
+#include "vrrp.h"
 
 extern data *conf_data;
 
@@ -84,87 +85,79 @@ static void dump_ssl(void)
 /* VRRP facility functions */
 static void free_vrrp(void *data)
 {
-  vrrp_instance *vrrp = data;
-  vrrp_rt *ptr = vrrp->vsrv;
+  vrrp_rt *vrrp = data;
 
   FREE(vrrp->iname);
   FREE_PTR(vrrp->isync);
-  FREE_PTR(ptr->vaddr);
-  FREE(ptr->ipsecah_counter);
-  FREE(ptr->vif->ifname);
-  FREE(ptr->vif);
-  FREE(ptr);
+  FREE_PTR(vrrp->lvs_syncd_if);
+  FREE_PTR(vrrp->vaddr);
+  FREE(vrrp->ipsecah_counter);
   FREE(vrrp);
 }
 static void dump_vrrp(void *data)
 {
-  vrrp_instance *vrrp = data;
-  vrrp_rt *ptr = vrrp->vsrv;
+  vrrp_rt *vrrp = data;
   int i;
 
   syslog(LOG_INFO, " VRRP Instance = %s", vrrp->iname);
   if (vrrp->isync)
     syslog(LOG_INFO, "   Sync with instance = %s", vrrp->isync);
-  if (ptr->init_state == VRRP_STATE_BACK)
+  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", ptr->vif->ifname);
-  syslog(LOG_INFO, "   Virtual Router ID = %d", ptr->vrid);
-  syslog(LOG_INFO, "   Priority = %d", ptr->priority);
-  syslog(LOG_INFO, "   Advert interval = %dsec", ptr->adver_int/TIMER_HZ);
-  if (ptr->preempt)
+  syslog(LOG_INFO, "   Runing on device = %s", IF_NAME(vrrp->ifp));
+  if (vrrp->lvs_syncd_if)
+    syslog(LOG_INFO, "   Runing LVS sync daemon on interface = %s"
+                   , vrrp->lvs_syncd_if);
+  syslog(LOG_INFO, "   Virtual Router ID = %d", vrrp->vrid);
+  syslog(LOG_INFO, "   Priority = %d", vrrp->priority);
+  syslog(LOG_INFO, "   Advert interval = %dsec", vrrp->adver_int/TIMER_HZ);
+  if (vrrp->preempt)
     syslog(LOG_INFO, "   Preempt Active");
-  if (ptr->vif->auth_type) {
+  if (vrrp->auth_type) {
     syslog(LOG_INFO, "   Authentication type = %s",
-               (ptr->vif->auth_type == VRRP_AUTH_AH)?"IPSEC_AH":"SIMPLE_PASSWORD" );
-    syslog(LOG_INFO, "   Password = %s", ptr->vif->auth_data);
+               (vrrp->auth_type == VRRP_AUTH_AH)?"IPSEC_AH":"SIMPLE_PASSWORD" );
+    syslog(LOG_INFO, "   Password = %s", vrrp->auth_data);
   }
-  syslog(LOG_INFO, "   VIP count = %d", ptr->naddr);
-  for (i = 0; i < ptr->naddr; i++)
-    syslog(LOG_INFO, "     VIP%d = %s", i+1, ip_ntoa(ptr->vaddr[i].addr));
+  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));
 }
 void alloc_vrrp(char *iname)
 {
   int size = strlen(iname);
-  vrrp_instance *new;
-  vrrp_rt *rt;
-  vrrp_if *vif;
   seq_counter *counter;
+  vrrp_rt *new;
 
   /* Allocate new VRRP structure */
-  new     = (vrrp_instance *)MALLOC(sizeof(vrrp_instance));
-  rt      = (vrrp_rt *)      MALLOC(sizeof(vrrp_rt));
-  vif     = (vrrp_if *)      MALLOC(sizeof(vrrp_if));
+  new     = (vrrp_rt *)      MALLOC(sizeof(vrrp_rt));
   counter = (seq_counter *)  MALLOC(sizeof(seq_counter));
 
   /* Build the structure */
-  new->vsrv           = rt;
-  rt->vif             = vif;
-  rt->ipsecah_counter = counter;
+  new->ipsecah_counter = counter;
 
   /* Set default values */
-  rt->wantstate  = VRRP_STATE_BACK;
-  rt->init_state = VRRP_STATE_BACK;
-  rt->adver_int  = TIMER_HZ;
-  new->iname = (char *)MALLOC(size+1);
+  new->wantstate  = VRRP_STATE_BACK;
+  new->init_state = VRRP_STATE_BACK;
+  new->adver_int  = TIMER_HZ;
+  new->iname      = (char *)MALLOC(size+1);
   memcpy(new->iname, iname, size);
 
   list_add(conf_data->vrrp, new);
 }
 void alloc_vrrp_vip(char *vip)
 {
-  vrrp_instance *vrrp = LIST_TAIL_DATA(conf_data->vrrp);
+  vrrp_rt *vrrp = LIST_TAIL_DATA(conf_data->vrrp);
   uint32_t ipaddr = inet_addr(vip);
-  vrrp_rt *ptr = vrrp->vsrv;
 
-  ptr->naddr++;
-  if (ptr->vaddr)
-    ptr->vaddr = REALLOC(ptr->vaddr, ptr->naddr*sizeof(*ptr->vaddr));
+  vrrp->naddr++;
+  if (vrrp->vaddr)
+    vrrp->vaddr = REALLOC(vrrp->vaddr, vrrp->naddr*sizeof(*vrrp->vaddr));
   else
-    ptr->vaddr = (vip_addr *)MALLOC(sizeof(*ptr->vaddr));
-  ptr->vaddr[ptr->naddr-1].addr = ipaddr;
-  ptr->vaddr[ptr->naddr-1].deletable = 0;
+    vrrp->vaddr = (vip_addr *)MALLOC(sizeof(*vrrp->vaddr));
+  vrrp->vaddr[vrrp->naddr-1].addr = ipaddr;
+  vrrp->vaddr[vrrp->naddr-1].set  = 0;
 }
 
 /* Virtual server facility functions */
@@ -306,18 +299,25 @@ void free_data(void)
   free_list(conf_data->vrrp);
   free_list(conf_data->vs);
 
-  FREE(conf_data->lvs_id);
-  FREE(conf_data->email_from);
+//  FREE(conf_data->lvs_id);
+//  FREE(conf_data->email_from);
   FREE(conf_data);
 }
 void dump_data(void)
 {
-  syslog(LOG_INFO, "------< Global definitions >------");
-  syslog(LOG_INFO, " LVS ID = %s", conf_data->lvs_id);
-  syslog(LOG_INFO, " Smtp server = %s", ip_ntoa(conf_data->smtp_server));
-  syslog(LOG_INFO, " Smtp server connection timeout = %d", conf_data->smtp_connection_to);
-  syslog(LOG_INFO, " Email notification from = %s", conf_data->email_from);
-  dump_list(conf_data->email);
+  if (conf_data->lvs_id             && 
+      conf_data->smtp_server        &&
+      conf_data->smtp_connection_to &&
+      conf_data->email_from) {
+    syslog(LOG_INFO, "------< Global definitions >------");
+    syslog(LOG_INFO, " LVS ID = %s", conf_data->lvs_id);
+    syslog(LOG_INFO, " Smtp server = %s", ip_ntoa(conf_data->smtp_server));
+    syslog(LOG_INFO, " Smtp server connection timeout = %d"
+                   , conf_data->smtp_connection_to);
+    syslog(LOG_INFO, " Email notification from = %s"
+                   , conf_data->email_from);
+    dump_list(conf_data->email);
+  }
 
   if (conf_data->ssl) {
     syslog(LOG_INFO, "------< SSL definitions >------");
diff --git a/data.h b/data.h
index 3d6b22d..dcd2f4e 100644 (file)
--- a/data.h
+++ b/data.h
@@ -5,7 +5,7 @@
  *
  * Part:        Dynamic data structure definition.
  *
- * Version:     $Id: data.h,v 0.5.3 2002/02/24 23:50:11 acassen Exp $
+ * Version:     $Id: data.h,v 0.5.5 2002/04/10 02:34:23 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
@@ -42,7 +42,6 @@
 
 /* local includes */
 #include "list.h"
-#include "vrrp.h"
 
 /* Daemon dynamic data structure definition */
 #define MAX_TIMEOUT_LENGTH     5
@@ -84,13 +83,6 @@ typedef struct _virtual_server {
   list                 rs;
 } virtual_server;
 
-/* VRRP instance definition */
-typedef struct _vrrp_instance {
-  char         *iname; /* Instance Name */
-  char         *isync; /* Instance Name to synchronize with */
-  vrrp_rt      *vsrv;  /* VRRP data */
-} vrrp_instance;
-
 /* email link list */
 typedef struct _email {
   char *addr;
index eed37cf..c016d36 100644 (file)
@@ -12,12 +12,12 @@ global_defs {
    lvs_id LVS_DEVEL
 }
 
-;SSL {
-  password password
-  ca /etc/keepalived/root.pem
-  certificate /etc/keepalived/dh1024.pem
-  key /etc/keepalived/client.pem
-}
+!SSL {
+!  password password
+!  ca /etc/keepalived/root.pem
+!  certificate /etc/keepalived/dh1024.pem
+!  key /etc/keepalived/client.pem
+!}
 
 vrrp_instance VI_1 {
     state MASTER
diff --git a/genhash/Makefile b/genhash/Makefile
new file mode 100644 (file)
index 0000000..3136b6e
--- /dev/null
@@ -0,0 +1,35 @@
+# Generated automatically from Makefile.in by configure.
+# Makefile
+#
+# Keepalived OpenSource project.
+#
+# Copyright (C) 2001, 2002 Alexandre Cassen, <acassen@linux-vs.org>
+
+EXEC = genhash
+
+prefix = /usr/local
+exec_prefix = ${prefix}
+bindir = ${exec_prefix}/bin
+
+CC = gcc
+CFLAGS = -g -O2 -Wall -Wunused -Wstrict-prototypes
+LDFLAGS = -lpopt -lssl -lcrypto  
+
+OBJS = main.o client.o common.o
+
+all:   $(EXEC)
+       strip $(EXEC)
+       @echo ""
+       @echo "Make complete"
+
+$(EXEC): $(OBJS)
+       $(CC) $(OBJS) -o $(EXEC) $(LDFLAGS)
+
+clean:
+       rm -f core *.o $(EXEC)
+
+clean-dist:
+       rm -f $(bindir)/$(EXEC)
+
+install:       
+       install -m 755 $(EXEC) $(bindir)/
index d9f63ce..c40d8fb 100644 (file)
@@ -34,7 +34,7 @@
 
 /* Build version */
 #define PROG    "genhash"
-#define VERSION "0.4.9 (05/12, 2001)"
+#define VERSION "0.5.3 (03/22, 2002)"
 
 /* HTTP/HTTPS GET command */
 #define REQUEST_TEMPLATE "GET %s HTTP/1.0\r\n" \
index ea77db9..e8b9e06 100644 (file)
@@ -7,7 +7,7 @@
  *              library to add/remove server MASQ rules to the kernel 
  *              firewall framework.
  *
- * Version:     $Id: ipfwwrapper.c,v 0.5.3 2002/02/24 23:50:11 acassen Exp $
+ * Version:     $Id: ipfwwrapper.c,v 0.5.5 2002/04/10 02:34:23 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
index fbeb92d..4ff0d15 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Part:        ipfwwrapper.c include file.
  *
- * Version:     $Id: ipfwwrapper.h,v 0.5.3 2002/02/24 23:50:11 acassen Exp $
+ * Version:     $Id: ipfwwrapper.h,v 0.5.5 2002/04/10 02:34:23 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
index 6812848..24a48b3 100644 (file)
@@ -6,7 +6,7 @@
  * Part:        IPVS Kernel wrapper. Use setsockopt call to add/remove
  *              server to/from the loadbalanced server pool.
  *  
- * Version:     $Id: ipvswrapper.c,v 0.5.3 2002/02/24 23:50:11 acassen Exp $
+ * Version:     $Id: ipvswrapper.c,v 0.5.5 2002/04/10 02:34:23 acassen Exp $
  * 
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *              
 
 #ifdef _KRNL_2_2_  /* KERNEL 2.2 LVS handling */
 
+int ipvs_syncd_cmd(int cmd, char *ifname, int state)
+{
+  syslog(LOG_INFO, "IPVS WRAPPER : Sync daemon not supported on kernel v2.2");
+  return IPVS_ERROR;
+}
+
 int ipvs_cmd(int cmd, virtual_server *vs, real_server *rs)
 {
   struct ip_masq_ctl ctl;
@@ -94,6 +100,46 @@ int ipvs_cmd(int cmd, virtual_server *vs, real_server *rs)
 
 #else /* KERNEL 2.4 LVS handling */
 
+int ipvs_syncd_cmd(int cmd, char *ifname, int state)
+{
+  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;
+}
+
 int ipvs_cmd(int cmd, virtual_server *vs, real_server *rs)
 {
   struct ip_vs_rule_user urule;
@@ -195,6 +241,43 @@ int ipvs_cmd(int cmd, virtual_server *vs, real_server *rs)
 #endif
 
 /*
+ * IPVS synchronization daemon state transition
+ */
+int ipvs_syncd_goto_master_thread(thread *thread)
+{
+  char *ifname = THREAD_ARG(thread);
+  ipvs_syncd_cmd(IPVS_STARTDAEMON, ifname, IPVS_MASTER);
+  return 0;
+}
+
+int ipvs_syncd_master_thread(thread *thread)
+{
+  char *ifname = THREAD_ARG(thread);
+  ipvs_syncd_cmd(IPVS_STOPDAEMON, ifname, IPVS_BACKUP);
+  thread_add_timer(master, ipvs_syncd_goto_master_thread
+                         , ifname
+                         , IPVS_CMD_DELAY);
+  return 0;
+}
+
+int ipvs_syncd_goto_backup_thread(thread *thread)
+{
+  char *ifname = THREAD_ARG(thread);
+  ipvs_syncd_cmd(IPVS_STARTDAEMON, ifname, IPVS_BACKUP);
+  return 0;
+}
+
+int ipvs_syncd_backup_thread(thread *thread)
+{
+  char *ifname = THREAD_ARG(thread);
+  ipvs_syncd_cmd(IPVS_STOPDAEMON, ifname, IPVS_MASTER);
+  thread_add_timer(master, ipvs_syncd_goto_backup_thread
+                         , ifname
+                         , IPVS_CMD_DELAY);
+  return 0;
+}
+
+/*
  * Source code from the ipvsadm.c Wensong code
  */
 
index c1ef762..0351f51 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Part:        ipvswrapper.c include file.
  *
- * Version:     $Id: ipvswrapper.h,v 0.5.3 2002/02/24 23:50:11 acassen Exp $
+ * Version:     $Id: ipvswrapper.h,v 0.5.5 2002/04/10 02:34:23 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
 #include <net/ip_vs.h>
 
 /* locale includes */
+#include "scheduler.h"
 #include "data.h"
 
-#define IPVS_ERROR   0
-#define IPVS_SUCCESS 1
+#define IPVS_ERROR     0
+#define IPVS_SUCCESS   1
+#define IPVS_CMD_DELAY 3
+
+#define IPVS_STARTDAEMON       IP_VS_SO_SET_STARTDAEMON
+#define IPVS_STOPDAEMON                IP_VS_SO_SET_STOPDAEMON
+#define IPVS_MASTER            IP_VS_STATE_MASTER
+#define IPVS_BACKUP            IP_VS_STATE_BACKUP
+
+extern thread_master *master;
 
 /* prototypes */
 extern int parse_timeout(char *buf, unsigned *timeout);
 extern int string_to_number(const char *s, int min, int max);
 extern int ipvs_cmd(int cmd, virtual_server *vserver, real_server *rserver);
+extern int ipvs_syncd_cmd(int cmd, char *ifname, int state);
+extern int ipvs_syncd_master_thread(thread *thread);
+extern int ipvs_syncd_backup_thread(thread *thread);
 
 #endif
index 14c2be1..fd233c4 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Part:        Manipulation functions for IPVS & IPFW wrappers.
  *
- * Version:     $id: ipwrapper.c,v 0.5.3 2002/02/24 23:50:11 acassen Exp $
+ * Version:     $id: ipwrapper.c,v 0.5.5 2002/04/10 02:34:23 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
@@ -36,7 +36,7 @@ int clear_service_vs(virtual_server *vs)
 
 #ifdef _KRNL_2_2_
     /* IPFW cleaning server entry if granularity = /32 */
-    if (vserver->nat_mask == HOST_NETMASK)
+    if (vs->nat_mask == HOST_NETMASK)
       if (!ipfw_cmd(IP_FW_CMD_DEL, vs, e->data))
         return 0;
 #endif
index 62fb58a..88bf760 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Part:        ipwrapper.c include file.
  *
- * Version:     $Id: ipwrapper.h,v 0.5.3 2002/02/24 23:50:11 acassen Exp $
+ * Version:     $Id: ipwrapper.h,v 0.5.5 2002/04/10 02:34:23 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
index 830ec9d..5f1be04 100644 (file)
--- a/layer4.c
+++ b/layer4.c
@@ -6,7 +6,7 @@
  * Part:        Layer4 checkers handling. Register worker threads &
  *              upper layer checkers.
  *
- * Version:     $Id: layer4.c,v 0.5.3 2002/02/24 23:50:11 acassen Exp $
+ * Version:     $Id: layer4.c,v 0.5.5 2002/04/10 02:34:23 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
@@ -23,6 +23,7 @@
 
 #include "layer4.h"
 #include "check_api.h"
+#include "utils.h"
 
 enum connect_result
 tcp_connect (int fd, uint32_t addr_ip, uint16_t addr_port)
index 3d79e39..658c22c 100644 (file)
--- a/layer4.h
+++ b/layer4.h
@@ -5,7 +5,7 @@
  *
  * Part:        layer4.c include file.
  *
- * Version:     $Id: layer4.h,v 0.5.3 2002/02/24 23:50:11 acassen Exp $
+ * Version:     $Id: layer4.h,v 0.5.5 2002/04/10 02:34:23 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
index e69de29..bfa78f5 100644 (file)
@@ -0,0 +1,12 @@
+# Makefile to make libipfwc.
+
+CC     = gcc
+COPTS   = -g -O
+CFLAGS = -Wall -Wunused $(COPTS)
+
+libipfwc.a: libipfwc.a(libipfwc.o)
+
+libipfwc.o: libipfwc.h ipfwc_kernel_headers.h
+
+clean:
+       rm -f *.a *.o *~
index 955e72f..e76726a 100644 (file)
@@ -444,7 +444,7 @@ struct ipfwc_fwrule *ipfwc_get_rules(unsigned int *num_rules, int zero)
 }
 
 /* Get raw socket. */
-int ipfwc_get_raw_socket(void)
+int ipfwc_get_raw_socket()
 {
        return sockfd;
 }
diff --git a/list.c b/list.c
index 995a33a..e7ef21d 100644 (file)
--- a/list.c
+++ b/list.c
@@ -5,7 +5,7 @@
  * 
  * Part:        List structure manipulation.
  *  
- * Version:     $Id: list.c,v 0.5.3 2002/02/24 23:50:11 acassen Exp $
+ * Version:     $Id: list.c,v 0.5.5 2002/04/10 02:34:23 acassen Exp $
  * 
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *              
diff --git a/list.h b/list.h
index 4895536..df28817 100644 (file)
--- a/list.h
+++ b/list.h
@@ -5,7 +5,7 @@
  * 
  * Part:        list.c include file.
  *  
- * Version:     $Id: list.h,v 0.5.3 2002/02/24 23:50:11 acassen Exp $
+ * Version:     $Id: list.h,v 0.5.5 2002/04/10 02:34:23 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
diff --git a/main.c b/main.c
index 50a02f9..1ab7c61 100644 (file)
--- a/main.c
+++ b/main.c
@@ -5,7 +5,7 @@
  *
  * Part:        Main program structure.
  *
- * Version:     $Id: main.c,v 0.5.3 2002/02/24 23:50:11 acassen Exp $
+ * Version:     $Id: main.c,v 0.5.5 2002/04/10 02:34:23 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
@@ -24,6 +24,7 @@
 #include "daemon.h"
 #include "memory.h"
 #include "parser.h"
+#include "vrrp_if.h"
 
 /* SIGHUP handler */
 void sighup(int sig)
@@ -70,7 +71,7 @@ void signal_init(void)
   signal_set(SIGINT,  sighup);
   signal_set(SIGTERM, sighup);
   signal_set(SIGKILL, sighup);
-  signal_set (SIGCHLD, sigchld);
+  signal_set(SIGCHLD, sigchld);
 }
 
 /* Usage function */
@@ -220,6 +221,9 @@ int main(int argc, char **argv)
   /* Create the master thread */
   master = thread_make_master();
 
+  /* Init interface queue */
+  init_interface_queue();
+
   /* Parse the configuration file */
   init_checkers_queue();
   init_keywords();
@@ -228,7 +232,9 @@ int main(int argc, char **argv)
     syslog(LOG_INFO, "Stopping "VERSION_STRING);
     closelog();
     thread_destroy_master(master);
+#ifdef _DEBUG_
     keepalived_free_final();
+#endif
     exit(0);
   }
 
@@ -236,7 +242,9 @@ int main(int argc, char **argv)
   if (!init_ssl_ctx()) {
     closelog();
     thread_destroy_master(master);
+#ifdef _DEBUG_
     keepalived_free_final();
+#endif
     exit(0);
   }
 
@@ -276,6 +284,7 @@ int main(int argc, char **argv)
   thread_destroy_master(master);
   clear_services();
   shutdown_vrrp_instances();
+  free_interface_queue();
   free_data();
 
   pidfile_rm();
diff --git a/main.h b/main.h
index e615b0b..5044e74 100644 (file)
--- a/main.h
+++ b/main.h
@@ -5,7 +5,7 @@
  *
  * Part:        Main program include file.
  *
- * Version:     $Id: main.h,v 0.5.3 2002/02/24 23:50:11 acassen Exp $
+ * Version:     $Id: main.h,v 0.5.5 2002/04/10 02:34:23 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
@@ -37,7 +37,7 @@
 #include "smtp.h"
 #include "vrrp.h"
 #include "check_api.h"
-//#include "check_ssl.h"
+#include "vrrp_netlink.h"
 
 /* global var */
 thread_master *master;
@@ -52,15 +52,15 @@ extern void register_vrrp_thread(void);
 /* Build version */
 #define PROG    "Keepalived"
 
-#define VERSION_CODE 0x000503
-#define DATE_CODE    0x160202
+#define VERSION_CODE 0x000505
+#define DATE_CODE    0x0a0402
 
 #define KEEPALIVED_VERSION(version)    \
        (version >> 16) & 0xFF,         \
        (version >> 8) & 0xFF,          \
        version & 0xFF
 
-#define VERSION_STRING PROG" v%d.%d.%d (%.2d/%.2d, 20%.2d)", \
+#define VERSION_STRING PROG" v%d.%d.%d (%.2d/%.2d, 20%.2d)\n", \
                KEEPALIVED_VERSION(VERSION_CODE), \
                KEEPALIVED_VERSION(DATE_CODE)
 #endif
index 3a9440d..63cfb31 100644 (file)
--- a/memory.c
+++ b/memory.c
@@ -6,7 +6,7 @@
  * Part:        Memory management framework. This framework is used to
  *              find any memory leak.
  *
- * Version:     $Id: memory.c,v 0.5.3 2002/02/24 23:50:11 acassen Exp $
+ * Version:     $Id: memory.c,v 0.5.5 2002/04/10 02:34:23 acassen Exp $
  *
  * Authors:     Alexandre Cassen, <acassen@linux-vs.org>
  *              Jan Holmberg, <jan@artech.net>
index a11cee0..3c6c5c6 100644 (file)
--- a/memory.h
+++ b/memory.h
@@ -5,7 +5,7 @@
  *
  * Part:        memory.c include file.
  *
- * Version:     $Id: memory.h,v 0.5.3 2002/02/24 23:50:11 acassen Exp $
+ * Version:     $Id: memory.h,v 0.5.5 2002/04/10 02:34:23 acassen Exp $
  *
  * Authors:     Alexandre Cassen, <acassen@linux-vs.org>
  *              Jan Holmberg, <jan@artech.net>
index e54ee8e..60244c7 100644 (file)
--- a/parser.c
+++ b/parser.c
@@ -7,7 +7,7 @@
  *              data structure representation the conf file representing
  *              the loadbalanced server pool.
  *  
- * Version:     $Id: parser.c,v 0.5.3 2002/02/24 23:50:11 acassen Exp $
+ * Version:     $Id: parser.c,v 0.5.5 2002/04/10 02:34:23 acassen Exp $
  * 
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *              
@@ -299,105 +299,111 @@ static void vrrp_handler(vector strvec)
 }
 static void vrrp_isync_handler(vector strvec)
 {
-  vrrp_instance *vrrp = LIST_TAIL_DATA(conf_data->vrrp);
+  vrrp_rt *vrrp = LIST_TAIL_DATA(conf_data->vrrp);
   vrrp->isync = set_value(strvec);
 }
 static void vrrp_state_handler(vector strvec)
 {
   char *str = VECTOR_SLOT(strvec, 1);
-  vrrp_instance *vrrp = LIST_TAIL_DATA(conf_data->vrrp);
-  vrrp_rt *rt = vrrp->vsrv;
+  vrrp_rt *vrrp = LIST_TAIL_DATA(conf_data->vrrp);
 
   if (!strcmp(str, "MASTER")) {
-    rt->wantstate  = VRRP_STATE_MAST;
-    rt->init_state = VRRP_STATE_MAST;
+    vrrp->wantstate  = VRRP_STATE_MAST;
+    vrrp->init_state = VRRP_STATE_MAST;
   } else {
-    rt->wantstate  = VRRP_STATE_BACK;
-    rt->init_state = VRRP_STATE_BACK;
+    vrrp->wantstate  = VRRP_STATE_BACK;
+    vrrp->init_state = VRRP_STATE_BACK;
   }
 }
 static void vrrp_int_handler(vector strvec)
 {
-  vrrp_instance *vrrp = LIST_TAIL_DATA(conf_data->vrrp);
-  vrrp->vsrv->vif->ifname = set_value(strvec);
+  vrrp_rt *vrrp = LIST_TAIL_DATA(conf_data->vrrp);
+  char *name = VECTOR_SLOT(strvec, 1);
+
+  vrrp->ifp = if_get_by_ifname(name);
 }
 static void vrrp_vrid_handler(vector strvec)
 {
-  vrrp_instance *vrrp = LIST_TAIL_DATA(conf_data->vrrp);
-  vrrp->vsrv->vrid = atoi(VECTOR_SLOT(strvec, 1));
+  vrrp_rt *vrrp = LIST_TAIL_DATA(conf_data->vrrp);
+  vrrp->vrid = atoi(VECTOR_SLOT(strvec, 1));
 
-  if (VRRP_IS_BAD_VID(vrrp->vsrv->vrid)) {
+  if (VRRP_IS_BAD_VID(vrrp->vrid)) {
     syslog(LOG_INFO, "VRRP Error : VRID not valid !\n");
     syslog(LOG_INFO, "             must be between 1 & 255. reconfigure !\n");
   }
 }
 static void vrrp_prio_handler(vector strvec)
 {
-  vrrp_instance *vrrp = LIST_TAIL_DATA(conf_data->vrrp);
-  vrrp->vsrv->priority = atoi(VECTOR_SLOT(strvec, 1));
+  vrrp_rt *vrrp = LIST_TAIL_DATA(conf_data->vrrp);
+  vrrp->priority = atoi(VECTOR_SLOT(strvec, 1));
 
-  if (VRRP_IS_BAD_PRIORITY(vrrp->vsrv->priority)) {
+  if (VRRP_IS_BAD_PRIORITY(vrrp->priority)) {
     syslog(LOG_INFO, "VRRP Error : Priority not valid !\n");
     syslog(LOG_INFO, "             must be between 1 & 255. reconfigure !\n");
     syslog(LOG_INFO, "             Using default value : 100\n");
-    vrrp->vsrv->priority = 100;
+    vrrp->priority = 100;
   }
 }
 static void vrrp_adv_handler(vector strvec)
 {
-  vrrp_instance *vrrp = LIST_TAIL_DATA(conf_data->vrrp);
-  vrrp->vsrv->adver_int = atoi(VECTOR_SLOT(strvec, 1));
+  vrrp_rt *vrrp = LIST_TAIL_DATA(conf_data->vrrp);
+  vrrp->adver_int = atoi(VECTOR_SLOT(strvec, 1));
 
-  if (VRRP_IS_BAD_ADVERT_INT(vrrp->vsrv->adver_int)) {
+  if (VRRP_IS_BAD_ADVERT_INT(vrrp->adver_int)) {
     syslog(LOG_INFO, "VRRP Error : Advert intervall not valid !\n");
     syslog(LOG_INFO, "             must be between less than 1sec.\n");
     syslog(LOG_INFO, "             Using default value : 1sec\n");
-    vrrp->vsrv->adver_int = 1;
+    vrrp->adver_int = 1;
   }
-  vrrp->vsrv->adver_int *= TIMER_HZ;
+  vrrp->adver_int *= TIMER_HZ;
 }
 static void vrrp_debug_handler(vector strvec)
 {
-  vrrp_instance *vrrp = LIST_TAIL_DATA(conf_data->vrrp);
-  vrrp->vsrv->debug = atoi(VECTOR_SLOT(strvec, 1));
+  vrrp_rt *vrrp = LIST_TAIL_DATA(conf_data->vrrp);
+  vrrp->debug = atoi(VECTOR_SLOT(strvec, 1));
 
-  if (VRRP_IS_BAD_DEBUG_INT(vrrp->vsrv->debug)) {
+  if (VRRP_IS_BAD_DEBUG_INT(vrrp->debug)) {
     syslog(LOG_INFO, "VRRP Error : Debug intervall not valid !\n");
     syslog(LOG_INFO, "             must be between 0-4\n");
-    vrrp->vsrv->debug = 0;
+    vrrp->debug = 0;
   }
 }
 static void vrrp_preempt_handler(vector strvec)
 {
-  vrrp_instance *vrrp = LIST_TAIL_DATA(conf_data->vrrp);
-  vrrp->vsrv->preempt = !vrrp->vsrv->preempt;
+  vrrp_rt *vrrp = LIST_TAIL_DATA(conf_data->vrrp);
+  vrrp->preempt = !vrrp->preempt;
 }
 static void vrrp_notify_handler(vector strvec)
 {
-  vrrp_instance *vrrp = LIST_TAIL_DATA(conf_data->vrrp);
+  vrrp_rt *vrrp = LIST_TAIL_DATA(conf_data->vrrp);
   char *str = VECTOR_SLOT(strvec, 1);
-  int size = sizeof(vrrp->vsrv->notify_file);
+  int size = sizeof(vrrp->notify_file);
 
-  memcpy(vrrp->vsrv->notify_file, str, size);
-  vrrp->vsrv->notify_exec = 1;
+  memcpy(vrrp->notify_file, str, size);
+  vrrp->notify_exec = 1;
+}
+static void vrrp_lvs_syncd_handler(vector strvec)
+{
+  vrrp_rt *vrrp = LIST_TAIL_DATA(conf_data->vrrp);
+  vrrp->lvs_syncd_if = set_value(strvec);
 }
 static void vrrp_auth_type_handler(vector strvec)
 {
-  vrrp_instance *vrrp = LIST_TAIL_DATA(conf_data->vrrp);
+  vrrp_rt *vrrp = LIST_TAIL_DATA(conf_data->vrrp);
   char *str = VECTOR_SLOT(strvec, 1);
 
   if (!strcmp(str, "AH"))
-    vrrp->vsrv->vif->auth_type = VRRP_AUTH_AH;
+    vrrp->auth_type = VRRP_AUTH_AH;
   else
-    vrrp->vsrv->vif->auth_type = VRRP_AUTH_PASS;
+    vrrp->auth_type = VRRP_AUTH_PASS;
 }
 static void vrrp_auth_pass_handler(vector strvec)
 {
-  vrrp_instance *vrrp = LIST_TAIL_DATA(conf_data->vrrp);
+  vrrp_rt *vrrp = LIST_TAIL_DATA(conf_data->vrrp);
   char *str = VECTOR_SLOT(strvec, 1);
-  int size = sizeof(vrrp->vsrv->vif->auth_data);
+  int size = sizeof(vrrp->auth_data);
 
-  memcpy(vrrp->vsrv->vif->auth_data, str, size);
+  memcpy(vrrp->auth_data, str, size);
 }
 static void vrrp_vip_handler(vector strvec)
 {
@@ -572,6 +578,7 @@ void init_keywords(void)
   install_keyword("preempt",                   &vrrp_preempt_handler);
   install_keyword("debug",                     &vrrp_debug_handler);
   install_keyword("notify",                    &vrrp_notify_handler);
+  install_keyword("lvs_sync_daemon_interface", &vrrp_lvs_syncd_handler);
   install_keyword("authentication",            NULL);
   install_sublevel();
     install_keyword("auth_type",               &vrrp_auth_type_handler);
index b531b15..0ad2fc3 100644 (file)
--- a/parser.h
+++ b/parser.h
@@ -5,7 +5,7 @@
  * 
  * Part:        cfreader.c include file.
  *  
- * Version:     $Id: parser.h,v 0.5.3 2002/02/24 23:50:11 acassen Exp $
+ * Version:     $Id: parser.h,v 0.5.5 2002/04/10 02:34:23 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
index c3efb9f..5fb9775 100644 (file)
--- a/pidfile.c
+++ b/pidfile.c
@@ -5,7 +5,7 @@
  *
  * Part:        pidfile utility.
  *
- * Version:     $Id: pidfile.c,v 0.5.3 2002/02/24 23:50:11 acassen Exp $
+ * Version:     $Id: pidfile.c,v 0.5.5 2002/04/10 02:34:23 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
index 13c020f..2ec8cc4 100644 (file)
--- a/pidfile.h
+++ b/pidfile.h
@@ -5,7 +5,7 @@
  *
  * Part:        pidfile.c include file.
  *
- * Version:     $Id: pidfile.h,v 0.5.3 2002/02/24 23:50:11 acassen Exp $
+ * Version:     $Id: pidfile.h,v 0.5.5 2002/04/10 02:34:23 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
index bb1626b..09a2d7f 100644 (file)
@@ -1,4 +1,4 @@
-# Configuration File for keepalived
+! Configuration File for keepalived
 
 global_defs {
    notification_email {
@@ -10,12 +10,12 @@ global_defs {
    lvs_id LVS_DEVEL
 }
 
-;SSL {
-  password password
-  ca /etc/keepalived/root.pem
-  certificate /etc/keepalived/dh1024.pem
-  key /etc/keepalived/client.pem
-}
+!SSL {
+!  password password
+!  ca /etc/keepalived/root.pem
+!  certificate /etc/keepalived/dh1024.pem
+!  key /etc/keepalived/client.pem
+!}
 
 vrrp_instance VI_1 {
     state MASTER
index 31d9111..d4db20e 100644 (file)
@@ -1,4 +1,4 @@
-# Configuration File for keepalived
+! Configuration File for keepalived
 
 global_defs {
    notification_email {
index acace02..7323609 100644 (file)
@@ -1,4 +1,4 @@
-# Configuration File for keepalived
+! Configuration File for keepalived
 
 global_defs {
    notification_email {
index 62592c8..049443b 100644 (file)
@@ -1,4 +1,4 @@
-# Configuration File for keepalived
+! Configuration File for keepalived
 
 global_defs {
    notification_email {
index 10327b2..09fb8dc 100644 (file)
@@ -1,4 +1,4 @@
-# Configuration File for keepalived
+! Configuration File for keepalived
 
 global_defs {
    notification_email {
diff --git a/samples/keepalived.conf.vrrp.lvs_syncd b/samples/keepalived.conf.vrrp.lvs_syncd
new file mode 100644 (file)
index 0000000..ac2edf5
--- /dev/null
@@ -0,0 +1,61 @@
+! Configuration File for keepalived
+
+vrrp_instance VI_1 {
+    state MASTER
+    interface eth0
+    lvs_sync_daemon_interface eth1
+    virtual_router_id 51
+    priority 150
+    advert_int 1
+    authentication {
+        auth_type PASS
+        auth_pass grr02
+    }
+    virtual_ipaddress {
+        192.168.200.16
+        192.168.200.17
+        192.168.200.18
+    }
+}
+
+vrrp_instance VI_2 {
+    interface eth0
+    virtual_router_id 52
+    priority 100
+    advert_int 1
+    virtual_ipaddress {
+        192.168.200.19
+        192.168.200.20
+        192.168.200.21
+    }
+    sync_instance VI_3
+}
+
+vrrp_instance VI_3 {
+    interface eth1
+    virtual_router_id 53
+    priority 100
+    advert_int 1
+    virtual_ipaddress {
+        192.168.201.19
+        192.168.201.20
+        192.168.201.21
+    }
+    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
+
+    real_server 192.168.201.100 80 {
+        weight 1
+        TCP_CHECK {
+            connect_timeout 3
+        }
+    }
+}
index f252960..59ba1d6 100644 (file)
@@ -1,4 +1,4 @@
-# Configuration File for keepalived
+! Configuration File for keepalived
 
 global_defs {
    notification_email {
index a8aa270..267fc1a 100644 (file)
@@ -7,7 +7,7 @@
  *              the thread management routine (thread.c) present in the 
  *              very nice zebra project (http://www.zebra.org).
  *
- * Version:     $Id: scheduler.c,v 0.5.3 2002/02/24 23:50:11 acassen Exp $
+ * Version:     $Id: scheduler.c,v 0.5.5 2002/04/10 02:34:23 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
index 9838e91..e0df99a 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Part:        scheduler.c include file.
  *
- * Version:     $Id: scheduler.h,v 0.5.3 2002/02/24 23:50:11 acassen Exp $
+ * Version:     $Id: scheduler.h,v 0.5.5 2002/04/10 02:34:23 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
diff --git a/smtp.c b/smtp.c
index b3c6d80..ebd3911 100644 (file)
--- a/smtp.c
+++ b/smtp.c
@@ -7,7 +7,7 @@
  *              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.3 2002/02/24 23:50:11 acassen Exp $
+ * Version:     $Id: smtp.c,v 0.5.5 2002/04/10 02:34:23 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
@@ -25,6 +25,7 @@
 #include "smtp.h"
 #include "memory.h"
 #include "list.h"
+#include "utils.h"
 
 extern data *conf_data;
 
diff --git a/smtp.h b/smtp.h
index f77f73f..c7e9484 100644 (file)
--- a/smtp.h
+++ b/smtp.h
@@ -5,7 +5,7 @@
  *
  * Part:        smtp.c include file.
  *
- * Version:     $Id: smtp.h,v 0.5.3 2002/02/24 23:50:11 acassen Exp $
+ * Version:     $Id: smtp.h,v 0.5.5 2002/04/10 02:34:23 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
diff --git a/timer.c b/timer.c
index bd839c2..3d24ef4 100644 (file)
--- a/timer.c
+++ b/timer.c
@@ -5,7 +5,7 @@
  * 
  * Part:        Timer manipulations.
  *  
- * Version:     $Id: timer.c,v 0.5.3 2002/02/24 23:50:11 acassen Exp $
+ * Version:     $Id: timer.c,v 0.5.5 2002/04/10 02:34:23 acassen Exp $
  * 
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *              
diff --git a/timer.h b/timer.h
index ec8922c..3823a00 100644 (file)
--- a/timer.h
+++ b/timer.h
@@ -5,7 +5,7 @@
  * 
  * Part:        timer.c include file.
  *  
- * Version:     $Id: timer.h,v 0.5.3 2002/02/24 23:50:11 acassen Exp $
+ * Version:     $Id: timer.h,v 0.5.5 2002/04/10 02:34:23 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
diff --git a/utils.c b/utils.c
index 959f09d..80faab8 100644 (file)
--- a/utils.c
+++ b/utils.c
@@ -5,7 +5,7 @@
  *
  * Part:        General program utils.
  *
- * Version:     $Id: utils.c,v 0.5.3 2002/02/24 23:50:11 acassen Exp $
+ * Version:     $Id: utils.c,v 0.5.5 2002/04/10 02:34:23 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
diff --git a/utils.h b/utils.h
index 1eb3d78..38424b0 100644 (file)
--- a/utils.h
+++ b/utils.h
@@ -5,7 +5,7 @@
  *
  * Part:        utils.h include file.
  *
- * Version:     $Id: utils.h,v 0.5.3 2002/02/24 23:50:11 acassen Exp $
+ * Version:     $Id: utils.h,v 0.5.5 2002/04/10 02:34:23 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
index 0c16aaf..c928d2b 100644 (file)
--- a/vector.c
+++ b/vector.c
@@ -5,7 +5,7 @@
  * 
  * Part:        Vector structure manipulation.
  *  
- * Version:     $Id: vector.c,v 0.5.3 2002/02/24 23:50:11 acassen Exp $
+ * Version:     $Id: vector.c,v 0.5.5 2002/04/10 02:34:23 acassen Exp $
  * 
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *              
index 047287d..9ce4931 100644 (file)
--- a/vector.h
+++ b/vector.h
@@ -5,7 +5,7 @@
  * 
  * Part:        vector.c include file.
  *  
- * Version:     $Id: vector.h,v 0.5.3 2002/02/24 23:50:11 acassen Exp $
+ * Version:     $Id: vector.h,v 0.5.5 2002/04/10 02:34:23 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
diff --git a/vrrp.c b/vrrp.c
index 83d00bf..1474d24 100644 (file)
--- a/vrrp.c
+++ b/vrrp.c
@@ -8,7 +8,7 @@
  *              master fails, a backup server takes over.
  *              The original implementation has been made by jerome etienne.
  *
- * Version:     $Id: vrrp.c,v 0.5.3 2002/02/24 23:50:11 acassen Exp $
+ * Version:     $Id: vrrp.c,v 0.5.5 2002/04/10 02:34:23 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
 
 /* local include */
 #include "vrrp_scheduler.h"
+#include "ipvswrapper.h"
 #include "vrrp.h"
 #include "memory.h"
 #include "list.h"
+#include "data.h"
+
+extern data *conf_data;
 
 /* Close all FDs >= a specified value */
 void closeall(int fd)
@@ -38,26 +42,26 @@ void closeall(int fd)
     close(fd++);
 }
 
-static char *notify_get_name(vrrp_rt *vsrv)
+static char *notify_get_name(vrrp_rt *vrrp)
 {
   static char notifyfile[FILENAME_MAX+1];
 
-  if (vsrv->notify_exec) {
-    if (vsrv->notify_file != NULL)
-      strncpy(notifyfile,vsrv->notify_file, FILENAME_MAX);
+  if (vrrp->notify_exec) {
+    if (vrrp->notify_file != NULL)
+      strncpy(notifyfile, vrrp->notify_file, FILENAME_MAX);
     else
-      snprintf( notifyfile, sizeof(notifyfile),"%s/" VRRP_NOTIFY_FORMAT
-                          , VRRP_NOTIFY_DFL
-                          , vsrv->vif->ifname
-                          , vsrv->vrid );
+      snprintf(notifyfile, sizeof(notifyfile),"%s/" VRRP_NOTIFY_FORMAT
+                         , VRRP_NOTIFY_DFL
+                         , IF_NAME(vrrp->ifp)
+                         , vrrp->vrid );
   }
   return notifyfile;
 }
 
 /* Execute extern script/program */
-static int notify_exec( vrrp_rt *vsrv , char *cmd)
+static int notify_exec(vrrp_rt *vrrp , char *cmd)
 {
-  char *name = notify_get_name(vsrv);
+  char *name = notify_get_name(vrrp);
   FILE *fOut = fopen(name, "r");
   static char mycmd[FILENAME_MAX + 1 + 32];
   char tmp[16];
@@ -92,21 +96,21 @@ static int notify_exec( vrrp_rt *vsrv , char *cmd)
   dup(0);
   dup(0);
 
-  name  = notify_get_name(vsrv);
+  name = notify_get_name(vrrp);
 
   if (strlen(name) + strlen(cmd) + 32 >  FILENAME_MAX + 32) {
-    syslog(LOG_INFO,"To long exec stmt");
+    syslog(LOG_INFO, "To long exec stmt");
     exit (1);
   }
 
-  strcpy(mycmd,name);
-  strcat(mycmd," ");
-  strcat(mycmd,cmd);
-  strcat(mycmd," ");
-  snprintf(tmp,16,"%d",vsrv->vrid);
+  strcpy(mycmd, name);
+  strcat(mycmd, " ");
+  strcat(mycmd, cmd);
+  strcat(mycmd, " ");
+  snprintf(tmp, 16, "%d", vrrp->vrid);
   strcat(mycmd, tmp);
 
-  if (vsrv->debug > 0)
+  if (vrrp->debug > 0)
    syslog(LOG_INFO, "Trying to exec %s", mycmd);
 
   err = system(mycmd);
@@ -153,113 +157,37 @@ static u_short in_csum( u_short *addr, int len, u_short csum)
   return (answer);
 }
 
-/* retrieve MAC address from interface name */
-static int hwaddr_get(char *ifname, char *addr, int addrlen)
-{
-  struct ifreq ifr;
-  int fd = socket(AF_INET, SOCK_DGRAM, 0);
-  int ret;
-
-  if (fd < 0) return (-1);
-  strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
-  ret = ioctl(fd, SIOCGIFHWADDR, (char *)&ifr);
-  memcpy(addr, ifr.ifr_hwaddr.sa_data, addrlen);
-  close(fd);
-  return ret;
-}
-
-/* resolve ipaddress from interface name */
-static uint32_t ifname_to_ip(const char *ifname)
-{
-  struct ifreq ifr;
-  int fd = socket(AF_INET, SOCK_DGRAM, 0);
-  uint32_t addr = 0;
-
-  if (fd < 0) return (-1);
-  strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
-  if (ioctl(fd, SIOCGIFADDR, (char *)&ifr) == 0) {
-    struct sockaddr_in *sin = (struct sockaddr_in *)&ifr.ifr_addr;
-    addr = ntohl(sin->sin_addr.s_addr);
-  }
-
-  close(fd);
-  return addr;
-}
-
-/* resolve interface index from interface name */
-int ifname_to_idx(const char *ifname)
-{
-  struct ifreq ifr;
-  int fd = socket(AF_INET, SOCK_DGRAM, 0);
-  int ifindex = -1;
-
-  if (fd < 0) return (-1);
-  strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
-  if (ioctl(fd, SIOCGIFINDEX, (char *)&ifr) == 0)
-    ifindex = ifr.ifr_ifindex;
-
-  close(fd);
-  return ifindex;
-}
-
-/* resolve ifname from index */
-static void index_to_ifname(const int ifindex, char *ifname)
-{
-  struct ifreq ifr;
-  int fd = socket(AF_INET, SOCK_DGRAM, 0);
-
-  if (fd < 0) return;
-
-  /* get interface name */
-  ifr.ifr_ifindex = ifindex;
-  if (ioctl(fd, SIOCGIFNAME, (char *)&ifr) == 0)
-    strncpy(ifname, ifr.ifr_name, sizeof(ifr.ifr_name));
-  close(fd);
-}
-
-/* resolve ipaddress from interface index */
-static uint32_t index_to_ip(const int ifindex)
-{
-  char ifname[IFNAMSIZ];
-
-  memset(&ifname, 0, IFNAMSIZ);
-  index_to_ifname(ifindex, ifname);
-
-  return(ifname_to_ip(ifname));
-}
-
 /*
  * add/remove VIP
  * retry must clear for each vip address Hoj:-
  */
-static int vrrp_handle_ipaddress(vrrp_rt *vsrv, int cmd)
+static int vrrp_handle_ipaddress(vrrp_rt *vrrp, int cmd)
 {
   int i, err = 0;
-  int retry;
-  int ifidx = ifname_to_idx(vsrv->vif->ifname);
+  int retry = 0;
+  int ifindex = IF_INDEX(vrrp->ifp);
 
-  for(i = 0; i < vsrv->naddr; i++ ) {
-    vip_addr *vadd = &vsrv->vaddr[i];
-    retry ^= retry;
-    if(!cmd && !vadd->deletable) continue;
+  for(i = 0; i < vrrp->naddr; i++ ) {
+    vip_addr *vadd = &vrrp->vaddr[i];
+    if(!cmd && !vadd->set) continue;
 retry:
-    if (netlink_address_ipv4(ifidx , ntohl(vadd->addr), cmd) < 0) {
+    if (netlink_address_ipv4(ifindex , ntohl(vadd->addr), cmd) < 0) {
       err = 1;
-      vadd->deletable = 0;
+      vadd->set = 0;
       syslog(LOG_INFO, "cant %s the address %s to %s\n"
                      , cmd ? "set" : "remove"
                      , ip_ntoa(vadd->addr)
-                     , vsrv->vif->ifname);
+                     , IF_NAME(vrrp->ifp));
       if (cmd == VRRP_IPADDRESS_ADD) {
         syslog(LOG_INFO, "try to delete eventual stalled ip");
-        netlink_address_ipv4(ifidx, ntohl(vadd->addr), VRRP_IPADDRESS_DEL);
-        if (!retry) {
+        netlink_address_ipv4(ifindex, ntohl(vadd->addr), VRRP_IPADDRESS_DEL);
+        if (retry < 4) {
           retry++;
           goto retry;
         }
       }
     } else {
-      vadd->deletable = 1;
+      vadd->set = 1;
     }
   }
   return err;
@@ -272,7 +200,7 @@ static int vrrp_dlt_len( vrrp_rt *rt )
 }
 
 /* IP header length */
-static int vrrp_iphdr_len(vrrp_rt *vsrv)
+static int vrrp_iphdr_len(vrrp_rt *vrrp)
 {
   return sizeof(struct iphdr);
 }
@@ -284,10 +212,10 @@ int vrrp_ipsecah_len(void)
 }
 
 /* VRRP header length */
-static int vrrp_hd_len(vrrp_rt *vsrv)
+static int vrrp_hd_len(vrrp_rt *vrrp)
 {
   return sizeof(vrrp_pkt)
-         + vsrv->naddr*sizeof(uint32_t)
+         + vrrp->naddr * sizeof(uint32_t)
          + VRRP_AUTH_LEN;
 }
 
@@ -295,7 +223,7 @@ static int vrrp_hd_len(vrrp_rt *vsrv)
  * IPSEC AH incoming packet check.
  * return 0 for a valid pkt, != 0 otherwise.
  */
-static int vrrp_in_chk_ipsecah(vrrp_rt *vsrv, char *buffer)
+static int vrrp_in_chk_ipsecah(vrrp_rt *vrrp, char *buffer)
 {
   struct iphdr *ip = (struct iphdr*)(buffer);
   ipsec_ah *ah = (ipsec_ah *)((char *)ip + (ip->ihl<<2));
@@ -314,12 +242,9 @@ static int vrrp_in_chk_ipsecah(vrrp_rt *vsrv, char *buffer)
    * in inbound processing, we increment seq_number counter to audit 
    * sender counter.
    */
-  vsrv->ipsecah_counter->seq_number++;
-  if (ah->seq_number >= vsrv->ipsecah_counter->seq_number) {
-#ifdef _DEBUG_
-//  syslog(LOG_DEBUG, "IPSEC AH : SEQUENCE NUMBER : %d\n", ah->seq_number);
-#endif
-    vsrv->ipsecah_counter->seq_number = ah->seq_number;
+  vrrp->ipsecah_counter->seq_number++;
+  if (ah->seq_number >= vrrp->ipsecah_counter->seq_number) {
+    vrrp->ipsecah_counter->seq_number = ah->seq_number;
   } else {
     syslog(LOG_INFO, "IPSEC AH : sequence number %d already proceeded."
                      " Packet droped", ah->seq_number);
@@ -341,8 +266,10 @@ static int vrrp_in_chk_ipsecah(vrrp_rt *vsrv, char *buffer)
   memset(ah->auth_data, 0, sizeof(ah->auth_data));
 
   /* Compute the ICV */
-  hmac_md5(buffer, vrrp_iphdr_len(vsrv)+vrrp_ipsecah_len()+vrrp_hd_len(vsrv),
-           vsrv->vif->auth_data, sizeof(vsrv->vif->auth_data), digest);
+  hmac_md5(buffer, vrrp_iphdr_len(vrrp) + vrrp_ipsecah_len() + vrrp_hd_len(vrrp)
+                 , vrrp->auth_data
+                 , sizeof(vrrp->auth_data)
+                 , digest);
 
   if (memcmp(backup_auth_data, digest, HMAC_MD5_TRUNC) != 0) {
     syslog(LOG_INFO, "IPSEC AH : invalid IPSEC HMAC-MD5 value."
@@ -355,12 +282,12 @@ static int vrrp_in_chk_ipsecah(vrrp_rt *vsrv, char *buffer)
 }
 
 /* check if ipaddr is present in VIP buffer */
-static int vrrp_in_chk_vips(vrrp_rt *vsrv, uint32_t ipaddr, unsigned char *buffer)
+static int vrrp_in_chk_vips(vrrp_rt *vrrp, uint32_t ipaddr, unsigned char *buffer)
 {
   int i;
   uint32_t ipbuf;
 
-  for (i=0; i < vsrv->naddr; i++) {
+  for (i=0; i < vrrp->naddr; i++) {
     bcopy(buffer+i*sizeof(uint32_t), &ipbuf, sizeof(uint32_t));
     if (ipaddr == ntohl(ipbuf)) return 1;
   }
@@ -372,17 +299,16 @@ static int vrrp_in_chk_vips(vrrp_rt *vsrv, uint32_t ipaddr, unsigned char *buffe
  * VRRP incoming packet check.
  * return 0 if the pkt is valid, != 0 otherwise.
  */
-static int vrrp_in_chk(vrrp_rt *vsrv, char *buffer)
+static int vrrp_in_chk(vrrp_rt *vrrp, char *buffer)
 {
   struct iphdr *ip = (struct iphdr*)(buffer);
   int ihl = ip->ihl << 2;
-  vrrp_if *vif = vsrv->vif;
   ipsec_ah *ah;
   vrrp_pkt *hd;
   unsigned char *vips;
   int i;
 
-  if (vif->auth_type == VRRP_AUTH_AH) {
+  if (vrrp->auth_type == VRRP_AUTH_AH) {
     ah = (ipsec_ah *)(buffer + sizeof(struct iphdr));
     hd = (vrrp_pkt *)(buffer + ihl + vrrp_ipsecah_len());
   } else {
@@ -417,7 +343,7 @@ static int vrrp_in_chk(vrrp_rt *vsrv, char *buffer)
   }
 
   /* MUST verify the VRRP checksum */
-  if (in_csum( (u_short*)hd, vrrp_hd_len(vsrv), 0)) {
+  if (in_csum( (u_short*)hd, vrrp_hd_len(vrrp), 0)) {
     syslog(LOG_INFO, "Invalid vrrp checksum");
     return VRRP_PACKET_KO;
   }
@@ -426,8 +352,8 @@ static int vrrp_in_chk(vrrp_rt *vsrv, char *buffer)
    * MUST perform authentication specified by Auth Type 
    * check the authentication type
    */
-  if (vif->auth_type != hd->auth_type) {    
-    syslog(LOG_INFO, "receive a %d auth, expecting %d!", vif->auth_type
+  if (vrrp->auth_type != hd->auth_type) {    
+    syslog(LOG_INFO, "receive a %d auth, expecting %d!", vrrp->auth_type
                    , hd->auth_type);
     return VRRP_PACKET_KO;
   }
@@ -435,17 +361,18 @@ static int vrrp_in_chk(vrrp_rt *vsrv, char *buffer)
   /* check the authentication if it is a passwd */
   if (hd->auth_type == VRRP_AUTH_PASS) {
     char *pw = (char *)ip + ntohs(ip->tot_len)
-                - sizeof(vif->auth_data);
-    if (memcmp( pw, vif->auth_data, sizeof(vif->auth_data))){
+                          - sizeof(vrrp->auth_data);
+    if (memcmp(pw, vrrp->auth_data, sizeof(vrrp->auth_data))) {
       syslog(LOG_INFO, "receive an invalid passwd!");
       return VRRP_PACKET_KO;
     }
   }
 
   /* MUST verify that the VRID is valid on the receiving interface */
-  if (vsrv->vrid != hd->vrid) {
-    syslog(LOG_INFO, "received VRID mismatch. Received %d, Expected %d", 
-                     hd->vrid, vsrv->vrid);
+  if (vrrp->vrid != hd->vrid) {
+    syslog(LOG_INFO, "received VRID mismatch. Received %d, Expected %d"
+                   , hd->vrid
+                   , vrrp->vrid);
     return VRRP_PACKET_DROP;
   }
 
@@ -453,16 +380,16 @@ static int vrrp_in_chk(vrrp_rt *vsrv, char *buffer)
    * MAY verify that the IP address(es) associated with the
    * VRID are valid
    */
-  if (vsrv->naddr != hd->naddr) {
+  if (vrrp->naddr != hd->naddr) {
     syslog(LOG_INFO, "receive an invalid ip number count associated with VRID!");
     return VRRP_PACKET_KO;
   }
 
-  for (i=0; i < vsrv->naddr; i++)
-    if (!vrrp_in_chk_vips(vsrv,vsrv->vaddr[i].addr,vips)) {
+  for (i=0; i < vrrp->naddr; i++)
+    if (!vrrp_in_chk_vips(vrrp, vrrp->vaddr[i].addr,vips)) {
       syslog(LOG_INFO, "ip address associated with VRID"
                        " not present in received packet : %d"
-                     , vsrv->vaddr[i].addr);
+                     , vrrp->vaddr[i].addr);
       syslog(LOG_INFO, "one or more VIP associated with"
                        " VRID mismatch actual MASTER advert");
       return VRRP_PACKET_KO;
@@ -472,22 +399,23 @@ static int vrrp_in_chk(vrrp_rt *vsrv, char *buffer)
    * MUST verify that the Adver Interval in the packet is the same as
    * the locally configured for this virtual router
    */
-  if (vsrv->adver_int/TIMER_HZ != hd->adver_int) {
+  if (vrrp->adver_int/TIMER_HZ != hd->adver_int) {
     syslog(LOG_INFO, "advertissement interval mismatch mine=%d rcved=%d"
-                   , vsrv->adver_int, hd->adver_int);
+                   , vrrp->adver_int
+                   , hd->adver_int);
     /* to prevent concurent VRID running => multiple master in 1 VRID */
     return VRRP_PACKET_DROP;
   }
 
   /* check the authenicaion if it is ipsec ah */
   if(hd->auth_type == VRRP_AUTH_AH)
-    return(vrrp_in_chk_ipsecah(vsrv, buffer));
+    return(vrrp_in_chk_ipsecah(vrrp, buffer));
 
   return VRRP_PACKET_OK;
 }
 
 /* build ARP header */
-static void vrrp_build_dlt(vrrp_rt *vsrv, char *buffer, int buflen)
+static void vrrp_build_arp(vrrp_rt *vrrp, char *buffer, int buflen)
 {
   /* hardcoded for ethernet */
   struct ether_header * eth = (struct ether_header *)buffer;
@@ -501,29 +429,29 @@ static void vrrp_build_dlt(vrrp_rt *vsrv, char *buffer, int buflen)
   eth->ether_dhost[5] = INADDR_VRRP_GROUP & 0xFF;
 
   /* source address -- rfc2338.7.3 */
-  memcpy(eth->ether_shost, vsrv->hwaddr, sizeof(vsrv->hwaddr));
+  memcpy(eth->ether_shost, vrrp->hwaddr, sizeof(vrrp->hwaddr));
 
   /* type */
   eth->ether_type = htons(ETHERTYPE_IP);
 }
 
 /* build IP header */
-static void vrrp_build_ip(vrrp_rt *vsrv, char *buffer, int buflen)
+static void vrrp_build_ip(vrrp_rt *vrrp, char *buffer, int buflen)
 {
   struct iphdr *ip = (struct iphdr *)(buffer);
 
   ip->ihl      = 5;
   ip->version  = 4;
   ip->tos      = 0;
-  ip->tot_len  = ip->ihl*4 + vrrp_hd_len(vsrv);
+  ip->tot_len  = ip->ihl*4 + vrrp_hd_len(vrrp);
   ip->tot_len  = htons(ip->tot_len);
-  ip->id       = ++vsrv->vif->ip_id;
+  ip->id       = ++vrrp->ip_id;
   ip->frag_off = 0;
   ip->ttl      = VRRP_IP_TTL;
 
   /* fill protocol type --rfc2402.2 */
-  ip->protocol = (vsrv->vif->auth_type == VRRP_AUTH_AH)?IPPROTO_IPSEC_AH:IPPROTO_VRRP;
-  ip->saddr    = htonl(vsrv->vif->ipaddr);
+  ip->protocol = (vrrp->auth_type == VRRP_AUTH_AH)?IPPROTO_IPSEC_AH:IPPROTO_VRRP;
+  ip->saddr    = IF_ADDR(vrrp->ifp);
   ip->daddr    = htonl(INADDR_VRRP_GROUP);
 
   /* checksum must be done last */
@@ -531,7 +459,7 @@ static void vrrp_build_ip(vrrp_rt *vsrv, char *buffer, int buflen)
 }
 
 /* build IPSEC AH header */
-static void vrrp_build_ipsecah(vrrp_rt *vsrv, char *buffer, int buflen)
+static void vrrp_build_ipsecah(vrrp_rt *vrrp, char *buffer, int buflen)
 {
   ICV_mutable_fields *ip_mutable_fields;
   unsigned char *digest;
@@ -545,7 +473,7 @@ static void vrrp_build_ipsecah(vrrp_rt *vsrv, char *buffer, int buflen)
   ah->next_header = IPPROTO_VRRP;
 
   /* update IP header total length value */
-  ip->tot_len = ip->ihl*4 + vrrp_ipsecah_len() + vrrp_hd_len(vsrv);
+  ip->tot_len = ip->ihl*4 + vrrp_ipsecah_len() + vrrp_hd_len(vrrp);
   ip->tot_len = htons(ip->tot_len);
 
   /* update ip checksum */
@@ -589,21 +517,24 @@ static void vrrp_build_ipsecah(vrrp_rt *vsrv, char *buffer, int buflen)
      In the current implementation if counter has cycled, we stop sending adverts and 
      become BACKUP. If all the master are down we reset the counter for becoming MASTER.
   */
-//  if (vsrv->ipsecah_counter->seq_number > 5) {
-  if (vsrv->ipsecah_counter->seq_number > 0xFFFFFFFD) {
-    vsrv->ipsecah_counter->cycle = 1;
+//  if (vrrp->ipsecah_counter->seq_number > 5) {
+  if (vrrp->ipsecah_counter->seq_number > 0xFFFFFFFD) {
+    vrrp->ipsecah_counter->cycle = 1;
   } else {
-    vsrv->ipsecah_counter->seq_number++;
+    vrrp->ipsecah_counter->seq_number++;
   }
 
-  ah->seq_number = vsrv->ipsecah_counter->seq_number;
+  ah->seq_number = vrrp->ipsecah_counter->seq_number;
 
   /* Compute the ICV & trunc the digest to 96bits
      => No padding needed.
      -- rfc2402.3.3.3.1.1.1 & rfc2401.5
   */
   digest = (unsigned char *)MALLOC(16*sizeof(unsigned char *));
-  hmac_md5(buffer, buflen,vsrv->vif->auth_data, sizeof(vsrv->vif->auth_data), digest);
+  hmac_md5(buffer, buflen
+                 , vrrp->auth_data
+                 , sizeof(vrrp->auth_data)
+                 , digest);
   memcpy(ah->auth_data, digest, HMAC_MD5_TRUNC);
 
   /* Restore the ip mutable fields */
@@ -617,71 +548,72 @@ static void vrrp_build_ipsecah(vrrp_rt *vsrv, char *buffer, int buflen)
 }
 
 /* build VRRP header */
-static int vrrp_build_vrrp(vrrp_rt *vsrv, int prio, char *buffer, int buflen)
+static int vrrp_build_vrrp(vrrp_rt *vrrp, int prio, char *buffer, int buflen)
 {
   int  i;
-  vrrp_if *vif = vsrv->vif;
   vrrp_pkt *hd  = (vrrp_pkt *)buffer;
   uint32_t *iparr  = (uint32_t *)((char *)hd+sizeof(*hd));
   
   hd->vers_type  = (VRRP_VERSION<<4) | VRRP_PKT_ADVERT;
-  hd->vrid  = vsrv->vrid;
-  hd->priority  = prio;
-  hd->naddr  = vsrv->naddr;
-  hd->auth_type  = vsrv->vif->auth_type;
-  hd->adver_int  = vsrv->adver_int/TIMER_HZ;
+  hd->vrid       = vrrp->vrid;
+  hd->priority   = prio;
+  hd->naddr      = vrrp->naddr;
+  hd->auth_type  = vrrp->auth_type;
+  hd->adver_int  = vrrp->adver_int/TIMER_HZ;
 
   /* copy the ip addresses */
-  for( i = 0; i < vsrv->naddr; i++ ){
-    iparr[i] = htonl(vsrv->vaddr[i].addr);
+  for( i = 0; i < vrrp->naddr; i++ ){
+    iparr[i] = htonl(vrrp->vaddr[i].addr);
   }
-  hd->chksum  = in_csum( (u_short*)hd, vrrp_hd_len(vsrv), 0);
 
   /* copy the passwd if the authentication is VRRP_AH_PASS */
-  if( vif->auth_type == VRRP_AUTH_PASS ){
-    char *pw = (char *)hd + sizeof(*hd) + vsrv->naddr*4;
-    memcpy(pw, vif->auth_data, sizeof(vif->auth_data));
+  if (vrrp->auth_type == VRRP_AUTH_PASS) {
+    char *pw = (char *)hd + sizeof(*hd) + vrrp->naddr*4;
+    memcpy(pw, vrrp->auth_data, sizeof(vrrp->auth_data));
   }
 
+  /* finaly compute vrrp checksum */
+  hd->chksum  = in_csum( (u_short*)hd, vrrp_hd_len(vrrp), 0);
+
   return(0);
 }
 
 /* build VRRP packet */
-static void vrrp_build_pkt(vrrp_rt *vsrv, int prio, char *buffer, int buflen)
+static void vrrp_build_pkt(vrrp_rt *vrrp, int prio, char *buffer, int buflen)
 {
   char *bufptr;
 
   bufptr = buffer;
 
   /* build the ethernet header */
-  vrrp_build_dlt(vsrv, buffer, buflen);
+  vrrp_build_arp(vrrp, buffer, buflen);
 
   /* build the ip header */
-  buffer += vrrp_dlt_len(vsrv);
-  buflen -= vrrp_dlt_len(vsrv);
-  vrrp_build_ip(vsrv, buffer, buflen);
+  buffer += vrrp_dlt_len(vrrp);
+  buflen -= vrrp_dlt_len(vrrp);
+  vrrp_build_ip(vrrp, buffer, buflen);
 
   /* build the vrrp header */
-  buffer += vrrp_iphdr_len(vsrv);
+  buffer += vrrp_iphdr_len(vrrp);
 
-  if (vsrv->vif->auth_type == VRRP_AUTH_AH)
+  if (vrrp->auth_type == VRRP_AUTH_AH)
     buffer += vrrp_ipsecah_len();
-  buflen -= vrrp_iphdr_len(vsrv);
+  buflen -= vrrp_iphdr_len(vrrp);
 
-  if (vsrv->vif->auth_type == VRRP_AUTH_AH)
+  if (vrrp->auth_type == VRRP_AUTH_AH)
     buflen -= vrrp_ipsecah_len();
-  vrrp_build_vrrp(vsrv, prio, buffer, buflen);
+  vrrp_build_vrrp(vrrp, prio, buffer, buflen);
 
   /* build the IPSEC AH header */
-  if (vsrv->vif->auth_type == VRRP_AUTH_AH) {
-    bufptr += vrrp_dlt_len(vsrv);
-    buflen += vrrp_ipsecah_len() + vrrp_iphdr_len(vsrv);;
-    vrrp_build_ipsecah(vsrv, bufptr, buflen);
+  if (vrrp->auth_type == VRRP_AUTH_AH) {
+    bufptr += vrrp_dlt_len(vrrp);
+    buflen += vrrp_ipsecah_len() + vrrp_iphdr_len(vrrp);;
+    vrrp_build_ipsecah(vrrp, bufptr, buflen);
   }
 }
 
 /* send VRRP packet */
-static int vrrp_send_pkt(vrrp_rt *vsrv, char *buffer, int buflen)
+static int vrrp_send_pkt(vrrp_rt *vrrp, char *buffer, int buflen)
 {
   struct sockaddr from;
   int len;
@@ -694,7 +626,7 @@ static int vrrp_send_pkt(vrrp_rt *vsrv, char *buffer, int buflen)
 
   /* build the address */
   memset(&from, 0 , sizeof(from));
-  strcpy(from.sa_data, vsrv->vif->ifname);
+  strcpy(from.sa_data, IF_NAME(vrrp->ifp));
 
 //print_buffer(buflen, buffer);
 
@@ -706,23 +638,23 @@ static int vrrp_send_pkt(vrrp_rt *vsrv, char *buffer, int buflen)
 }
 
 /* send VRRP advertissement */
-static int vrrp_send_adv(vrrp_rt *vsrv, int prio)
+static int vrrp_send_adv(vrrp_rt *vrrp, int prio)
 {
   int buflen, ret;
   char *buffer;
 
   /* alloc the memory */
-  buflen = vrrp_dlt_len(vsrv) + vrrp_iphdr_len(vsrv) + vrrp_hd_len(vsrv);
-  if (vsrv->vif->auth_type == VRRP_AUTH_AH)
+  buflen = vrrp_dlt_len(vrrp) + vrrp_iphdr_len(vrrp) + vrrp_hd_len(vrrp);
+  if (vrrp->auth_type == VRRP_AUTH_AH)
     buflen += vrrp_ipsecah_len();
 
   buffer = MALLOC(buflen);
 
   /* build the packet  */
-  vrrp_build_pkt(vsrv, prio, buffer, buflen);
+  vrrp_build_pkt(vrrp, prio, buffer, buflen);
 
   /* send it */
-  ret = vrrp_send_pkt(vsrv, buffer, buflen);
+  ret = vrrp_send_pkt(vrrp, buffer, buflen);
 
   /* free the memory */
   FREE(buffer);
@@ -730,24 +662,24 @@ static int vrrp_send_adv(vrrp_rt *vsrv, int prio)
 }
 
 /* Received packet processing */
-int vrrp_check_packet(vrrp_rt *vsrv, char *buf, int buflen)
+int vrrp_check_packet(vrrp_rt *vrrp, char *buf, int buflen)
 {
   int ret;
 
   if (buflen > 0) {
-    ret = vrrp_in_chk(vsrv, buf);
+    ret = vrrp_in_chk(vrrp, buf);
 
     if (ret == VRRP_PACKET_DROP) {
-      syslog(LOG_INFO, "Sync instance needed on %s !!!",
-                       vsrv->vif->ifname);
+      syslog(LOG_INFO, "Sync instance needed on %s !!!"
+                     , IF_NAME(vrrp->ifp));
     }
 
     if (ret == VRRP_PACKET_KO)
-      syslog(LOG_INFO, "bogus VRRP packet received on %s !!!",
-                       vsrv->vif->ifname);
+      syslog(LOG_INFO, "bogus VRRP packet received on %s !!!"
+                     , IF_NAME(vrrp->ifp));
 //    else
-//      syslog(LOG_INFO, "Success receiving VRRP packet on %s.",
-//                       vsrv->vif->ifname);
+//      syslog(LOG_INFO, "Success receiving VRRP packet on %s."
+//                     , IF_NAME(vrrp->ifp));
     return ret;
   }
 
@@ -755,7 +687,7 @@ int vrrp_check_packet(vrrp_rt *vsrv, char *buf, int buflen)
 }
 
 /* send a gratuitous ARP packet */
-static int send_gratuitous_arp(vrrp_rt *vsrv, int addr)
+static int send_gratuitous_arp(vrrp_rt *vrrp, int addr)
 {
   struct m_arphdr {
     unsigned short int ar_hrd;          /* Format of hardware address.  */
@@ -773,8 +705,8 @@ static int send_gratuitous_arp(vrrp_rt *vsrv, int addr)
   char buf[sizeof(struct m_arphdr) + ETHER_HDR_LEN];
   char buflen = sizeof(struct m_arphdr) + ETHER_HDR_LEN;
   struct ether_header *eth = (struct ether_header *)buf;
-  struct m_arphdr *arph = (struct m_arphdr *)(buf + vrrp_dlt_len(vsrv));
-  char  *hwaddr = vsrv->vif->hwaddr;
+  struct m_arphdr *arph = (struct m_arphdr *)(buf + vrrp_dlt_len(vrrp));
+  char  *hwaddr = IF_HWADDR(vrrp->ifp);
   int  hwlen = ETH_ALEN;
 
   /* hardcoded for ethernet */
@@ -793,87 +725,116 @@ static int send_gratuitous_arp(vrrp_rt *vsrv, int addr)
   addr = htonl(addr);
   memcpy(arph->__ar_sip, &addr, sizeof(addr));
   memcpy(arph->__ar_tip, &addr, sizeof(addr));
-  return vrrp_send_pkt(vsrv, buf, buflen);
+  return vrrp_send_pkt(vrrp, buf, buflen);
 }
 
 /* Gratuitous ARP on each VIP */
-void vrrp_send_gratuitous_arp(vrrp_instance *vrrp_instance)
+void vrrp_send_gratuitous_arp(vrrp_rt *vrrp)
 {
   int  i, j;
-  vrrp_rt *vsrv = vrrp_instance->vsrv;
 
   /* send gratuitous arp for each virtual ip */
   for (j = 0; j < 5; j++)
-    for (i = 0; i < vsrv->naddr; i++)
-      send_gratuitous_arp(vsrv, vsrv->vaddr[i].addr);
+    for (i = 0; i < vrrp->naddr; i++)
+      send_gratuitous_arp(vrrp, ntohl(vrrp->vaddr[i].addr));
 }
 
 /* becoming master */
-void vrrp_state_goto_master(vrrp_instance *vrrp_instance)
+void vrrp_state_goto_master(vrrp_rt *vrrp)
 {
-  vrrp_rt *vsrv = vrrp_instance->vsrv;
-
   /* add the ip addresses */
-  vrrp_handle_ipaddress(vsrv, VRRP_IPADDRESS_ADD);
+  vrrp_handle_ipaddress(vrrp, VRRP_IPADDRESS_ADD);
 
   /* send an advertisement */
-  vrrp_send_adv(vsrv, vsrv->priority);
+  vrrp_send_adv(vrrp, vrrp->priority);
 
   /* remotes arp tables update */
-  vrrp_send_gratuitous_arp(vrrp_instance);
-
-  syslog(LOG_INFO, "VRRP_Instance(%s) Entering MASTER STATE"
-                 , vrrp_instance->iname);
-
-  if (vsrv->notify_exec) {
-    notify_exec(vsrv, "master");
-    if (vsrv->debug > 0)
+  syslog(LOG_INFO, "Sending gratuitous ARP on %s"
+                 , IF_NAME(vrrp->ifp));
+  vrrp_send_gratuitous_arp(vrrp);
+
+  /* Check if notify is needed */
+  if (vrrp->notify_exec) {
+    notify_exec(vrrp, "master");
+    if (vrrp->debug > 0)
       syslog(LOG_INFO, "notify:%s, flg:%d"
-                     , vsrv->notify_file
-                     , vsrv->notify_exec);
+                     , vrrp->notify_file
+                     , vrrp->notify_exec);
   }
 
-  vsrv->state = VRRP_STATE_MAST;
+  /* Check if sync daemon handling is needed */
+  if (vrrp->lvs_syncd_if)
+    thread_add_timer(master, ipvs_syncd_master_thread
+                           , vrrp->lvs_syncd_if
+                           , IPVS_CMD_DELAY);
+
+  if (vrrp->wantstate == VRRP_STATE_MAST) {
+    vrrp->state = VRRP_STATE_MAST;
+    syslog(LOG_INFO, "VRRP_Instance(%s) Entering MASTER STATE"
+                   , vrrp->iname);
+  } else {
+    vrrp->state = VRRP_STATE_DUMMY_MAST;
+    syslog(LOG_INFO, "VRRP_Instance(%s) Entering DUMMY_MASTER STATE"
+                   , vrrp->iname);
+  }
 }
 
 /* leaving master state */
-static void vrrp_restore_interface(vrrp_rt *vsrv, int advF)
+static void vrrp_restore_interface(vrrp_rt *vrrp, int advF)
 {
   /* remove the ip addresses */
-  vrrp_handle_ipaddress(vsrv, VRRP_IPADDRESS_DEL);
+  vrrp_handle_ipaddress(vrrp, VRRP_IPADDRESS_DEL);
 
   /* if we stop vrrp, warn the other routers to speed up the recovery */
   if (advF)
-    vrrp_send_adv(vsrv, VRRP_PRIO_STOP);
+    vrrp_send_adv(vrrp, VRRP_PRIO_STOP);
 }
 
-void vrrp_state_leave_master(vrrp_instance *instance)
+void vrrp_state_leave_master(vrrp_rt *vrrp)
 {
-  vrrp_rt *vsrv = instance->vsrv;
-
   /* Remove VIPs */
-  vrrp_restore_interface(vsrv, 0);
-
-  syslog(LOG_INFO, "VRRP_Instance(%s) Entering BACKUP STATE"
-                 , instance->iname);
-
-  if (vsrv->notify_exec) {
-    notify_exec(vsrv, "backup");
-    if  (vsrv->debug > 0)
+  vrrp_restore_interface(vrrp, 0);
+
+  if (vrrp->wantstate == VRRP_STATE_BACK)
+    syslog(LOG_INFO, "VRRP_Instance(%s) Entering BACKUP STATE"
+                   , vrrp->iname);
+  if (vrrp->wantstate == VRRP_STATE_GOTO_FAULT)
+    syslog(LOG_INFO, "VRRP_Instance(%s) Entering FAULT STATE"
+                   , vrrp->iname);
+
+  /* Check if notify is needed */
+  if (vrrp->notify_exec) {
+    if (vrrp->wantstate == VRRP_STATE_BACK)
+      notify_exec(vrrp, "backup");
+    if (vrrp->wantstate == VRRP_STATE_GOTO_FAULT)
+      notify_exec(vrrp, "fault");
+    if  (vrrp->debug > 0)
       syslog(LOG_INFO, "notify:%s, flg:%d"
-                     , vsrv->notify_file
-                     , vsrv->notify_exec);
+                     , vrrp->notify_file
+                     , vrrp->notify_exec);
   }
 
-  /* register the vrrp backup handler */
-  vsrv->state = VRRP_STATE_BACK;
+  /* Check if sync daemon handling is needed */
+  if (vrrp->lvs_syncd_if)
+    thread_add_timer(master, ipvs_syncd_backup_thread
+                           , vrrp->lvs_syncd_if
+                           , IPVS_CMD_DELAY);
+
+  /* set the new vrrp state */
+  switch (vrrp->wantstate) {
+    case VRRP_STATE_BACK:
+      vrrp->state = vrrp->wantstate;
+      break;
+    case VRRP_STATE_GOTO_FAULT:
+      vrrp->state = VRRP_STATE_FAULT;
+      break;
+  }
 }
 
 /* BACKUP state processing */
-void vrrp_state_backup(vrrp_instance *instance, char *buf, int buflen)
+void vrrp_state_backup(vrrp_rt *vrrp, char *buf, int buflen)
 {
   int ret      = 0;
-  vrrp_rt      *vsrv = instance->vsrv;
   struct iphdr *iph  = (struct iphdr *)buf;
   vrrp_pkt     *hd   = NULL;
 
@@ -888,38 +849,42 @@ void vrrp_state_backup(vrrp_instance *instance, char *buf, int buflen)
   }
 
   /* Process the incoming packet */
-  ret = vrrp_check_packet(vsrv, buf, buflen);
+  ret = vrrp_check_packet(vrrp, buf, buflen);
 
   if (ret == VRRP_PACKET_KO   || 
       ret == VRRP_PACKET_NULL) {
     syslog(LOG_INFO, "VRRP_Instance(%s) ignoring received advertisment..."
-                   , instance->iname);
-    vsrv->ms_down_timer = 3 * vsrv->adver_int + VRRP_TIMER_SKEW(vsrv);
+                   , vrrp->iname);
+    vrrp->ms_down_timer = 3 * vrrp->adver_int + VRRP_TIMER_SKEW(vrrp);
   } else if (hd->priority == 0) {
-    vsrv->ms_down_timer = VRRP_TIMER_SKEW(vsrv);
-  } else if( !vsrv->preempt || hd->priority >= vsrv->priority ) {
-    vsrv->ms_down_timer = 3 * vsrv->adver_int + VRRP_TIMER_SKEW(vsrv);
+    vrrp->ms_down_timer = VRRP_TIMER_SKEW(vrrp);
+  } else if( !vrrp->preempt || hd->priority >= vrrp->priority ) {
+    vrrp->ms_down_timer = 3 * vrrp->adver_int + VRRP_TIMER_SKEW(vrrp);
   }
 }
 
 /* MASTER state processing */
-void vrrp_state_master_tx(vrrp_instance *instance, const int prio)
+void vrrp_state_master_tx(vrrp_rt *vrrp, const int prio)
 {
-  vrrp_rt *vsrv = instance->vsrv;
-
   if (prio == VRRP_PRIO_OWNER)
-    vrrp_send_adv(vsrv, VRRP_PRIO_OWNER);
+    vrrp_send_adv(vrrp, VRRP_PRIO_OWNER);
   else
-    vrrp_send_adv(vsrv, vsrv->priority);
+    vrrp_send_adv(vrrp, vrrp->priority);
 }
 
-int vrrp_state_master_rx(vrrp_instance *instance, char *buf, int buflen)
+int vrrp_state_master_rx(vrrp_rt *vrrp, char *buf, int buflen)
 {
   int ret            = 0;
-  vrrp_rt      *vsrv = instance->vsrv;
   struct iphdr *iph  = (struct iphdr *)buf;
   vrrp_pkt     *hd   = NULL; 
 
+  /* return on link failure */
+  if (vrrp->wantstate == VRRP_STATE_GOTO_FAULT) {
+    vrrp->ms_down_timer = 3 * vrrp->adver_int + VRRP_TIMER_SKEW(vrrp);
+    vrrp->state = VRRP_STATE_FAULT;
+    return 1;
+  }
+
   /* Fill the VRRP header */
   switch (iph->protocol) {
     case IPPROTO_IPSEC_AH:
@@ -931,41 +896,80 @@ int vrrp_state_master_rx(vrrp_instance *instance, char *buf, int buflen)
   }
 
   /* Process the incoming packet */
-  ret = vrrp_check_packet(vsrv, buf, buflen);
+  ret = vrrp_check_packet(vrrp, buf, buflen);
 
   if (ret == VRRP_PACKET_KO   ||
       ret == VRRP_PACKET_NULL ||
       ret == VRRP_PACKET_DROP) {
     syslog(LOG_INFO, "VRRP_Instance(%s) Dropping received VRRP packet..."
-                   , instance->iname);
-    vrrp_send_adv(vsrv, vsrv->priority);
+                   , vrrp->iname);
+    vrrp_send_adv(vrrp, vrrp->priority);
     return 0;
   } else if (hd->priority == 0) {
-    vrrp_send_adv(vsrv, vsrv->priority);
+    vrrp_send_adv(vrrp, vrrp->priority);
     return 0;
-  } else if( hd->priority > vsrv->priority ||
-            (hd->priority == vsrv->priority &&
-            ntohl(iph->saddr) > vsrv->vif->ipaddr)) {
-    vsrv->ms_down_timer = 3 * vsrv->adver_int + VRRP_TIMER_SKEW(vsrv);
-    vsrv->state = VRRP_STATE_BACK;
+  } else if (hd->priority > vrrp->priority   ||
+             (hd->priority == vrrp->priority &&
+             ntohl(iph->saddr) > IF_ADDR(vrrp->ifp))) {
+    syslog(LOG_INFO, "VRRP_Instance(%s) Received higher prio advert"
+                   , vrrp->iname);
+    syslog(LOG_INFO, "VRRP_Instance(%s) Entering BACKUP state"
+                   , vrrp->iname);
+    vrrp->ms_down_timer = 3 * vrrp->adver_int + VRRP_TIMER_SKEW(vrrp);
+    vrrp->state = VRRP_STATE_BACK;
     return 1;
   }
 
   return 0;
 }
 
+int vrrp_state_fault_rx(vrrp_rt *vrrp, char *buf, int buflen)
+{
+  int ret            = 0;
+  struct iphdr *iph  = (struct iphdr *)buf;
+  vrrp_pkt     *hd   = NULL; 
+
+  /* Fill the VRRP header */
+  switch (iph->protocol) {
+    case IPPROTO_IPSEC_AH:
+      hd  = (vrrp_pkt *)((char *)iph + (iph->ihl<<2) + vrrp_ipsecah_len());
+      break;
+    case IPPROTO_VRRP:
+      hd  = (vrrp_pkt *)((char *)iph + (iph->ihl<<2));
+      break;
+  }
+
+  /* Process the incoming packet */
+  ret = vrrp_check_packet(vrrp, buf, buflen);
+
+  if (ret == VRRP_PACKET_KO   ||
+      ret == VRRP_PACKET_NULL ||
+      ret == VRRP_PACKET_DROP) {
+    syslog(LOG_INFO, "VRRP_Instance(%s) Dropping received VRRP packet..."
+                   , vrrp->iname);
+    vrrp_send_adv(vrrp, vrrp->priority);
+    return 0;
+  } else if (vrrp->priority > hd->priority ||
+             hd->priority == VRRP_PRIO_OWNER)
+    return 1;
+
+printf("Local prio: %d, remote prio: %d\n", vrrp->priority, hd->priority);
+
+  return 0;
+}
+
 /* check for minimum configuration requirements */
-static int chk_min_cfg(vrrp_rt *vsrv)
+static int chk_min_cfg(vrrp_rt *vrrp)
 {
-  if( vsrv->naddr == 0 ){
+  if (vrrp->naddr == 0) {
     syslog(LOG_INFO, "provide at least one ip for the virtual server");
     return 0;
   }
-  if( vsrv->vrid == 0 ){
+  if (vrrp->vrid == 0) {
     syslog(LOG_INFO, "the virtual id must be set!");
     return 0;
   }
-  if( vsrv->vif->ipaddr == 0 ){
+  if (!IF_ADDR(vrrp->ifp)) {
     syslog(LOG_INFO, "the interface ipaddr must be set!");
     return 0;
   }
@@ -977,9 +981,19 @@ static int chk_min_cfg(vrrp_rt *vsrv)
 int open_vrrp_socket(const int proto, const int index)
 {
   struct ip_mreqn req_add;
-  char ifname[IFNAMSIZ];
+  interface *ifp;
   int fd;
   int ret;
+  int retry_num = 0;
+
+  /* Retreive interface */
+  ifp = if_get_by_ifindex(index);
+
+  if (!IF_ISUP(ifp)) {
+    syslog(LOG_INFO, "Kernel is reporting: Interface %s is DOWN"
+                   , IF_NAME(ifp));
+    return -1;
+  }
 
   /* open the socket */
   fd = socket(AF_INET, SOCK_RAW, proto);
@@ -998,17 +1012,18 @@ int open_vrrp_socket(const int proto, const int index)
    * Needed for filter multicasted advert per interface.
    * 
    * -- If you read this !!! and know the answer to the question
-   *    please feal free to answer me ! :)
+   *    please feel free to answer me ! :)
    */
-  memset(ifname, 0, IFNAMSIZ);
-  index_to_ifname(index, ifname);
-  ret = setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE,
-                   ifname, strlen(ifname)+1);
+  ret = setsockopt(fd, SOL_SOCKET
+                     , SO_BINDTODEVICE
+                     , IF_NAME(ifp)
+                     , strlen(IF_NAME(ifp))+1);
   if (ret < 0) {
     int  err = errno;
-    syslog(LOG_INFO, "cant bind to device %s. errno=%d. (try to run it as root)",
-                     ifname, err);
-    close(fd); /* sd leak handle */
+    syslog(LOG_INFO, "cant bind to device %s. errno=%d. (try to run it as root)"
+                   , IF_NAME(ifp)
+                   , err);
+    close(fd);
     return -1;
   }
 
@@ -1019,80 +1034,137 @@ int open_vrrp_socket(const int proto, const int index)
    */
   memset(&req_add, 0, sizeof (req_add));
   req_add.imr_multiaddr.s_addr = htonl(INADDR_VRRP_GROUP);
-  req_add.imr_address.s_addr = htonl(index_to_ip(index));
-  req_add.imr_ifindex = index;
-  ret = setsockopt(fd, IPPROTO_IP, IP_ADD_MEMBERSHIP,
-                   (char *)&req_add, sizeof(struct ip_mreqn));
+  req_add.imr_address.s_addr   = IF_ADDR(ifp);
+  req_add.imr_ifindex          = IF_INDEX(ifp);
+
+  /* -> Need to handle multicast convergance after takeover.
+   * We retry until multicast is available on the interface.
+   * After VRRP_MCAST_RETRY we assume interface doesn't support
+   * multicast then exist with error.
+   * -> This can sound a little nasty since it degrade a little
+   * the global scheduling timers.
+   */
+moretry:
+  ret = setsockopt(fd, IPPROTO_IP
+                     , IP_ADD_MEMBERSHIP
+                     , (char *)&req_add
+                     , sizeof(struct ip_mreqn));
   if (ret < 0) {
-    int  err = errno;
-    syslog(LOG_INFO, "cant do IP_ADD_MEMBERSHIP errno=%d", err);
+    syslog(LOG_INFO, "cant do IP_ADD_MEMBERSHIP errno=%s (%d)"
+                   , strerror(errno)
+                   , errno);
+    if (errno == 19) {
+      retry_num++;
+      if (retry_num > VRRP_MCAST_RETRY) {
+        syslog(LOG_INFO, "cant do IP_ADD_MEMBERSHIP after %d retry errno=%s"
+                       , VRRP_MCAST_RETRY
+                       , strerror(errno));
+        return -1;
+      }
+      sleep(1); /* FIXME: Beurk... Very nasty... !!! */
+      goto moretry;
+    }
     return -1;
   }
 
   return fd;
 }
 
+void close_vrrp_socket(vrrp_rt *vrrp)
+{
+  struct ip_mreqn req_add;
+  int ret = 0;
 
-extern data *conf_data;
+  /* Leaving the VRRP multicast group */
+  memset(&req_add, 0, sizeof (req_add));
+  req_add.imr_multiaddr.s_addr = htonl(INADDR_VRRP_GROUP);
+  req_add.imr_address.s_addr   = IF_ADDR(vrrp->ifp);
+  req_add.imr_ifindex          = IF_INDEX(vrrp->ifp);
+  ret = setsockopt(vrrp->fd, IPPROTO_IP
+                           , IP_DROP_MEMBERSHIP
+                           , (char *)&req_add
+                           , sizeof(struct ip_mreqn));
+  if (ret < 0) {
+    syslog(LOG_INFO, "cant do IP_DROP_MEMBERSHIP errno=%s (%d)"
+                   , strerror(errno)
+                   , errno);
+    return;
+  }
+
+  /* Finally close the desc */
+  close(vrrp->fd);
+}
+
+void new_vrrp_socket(vrrp_rt *vrrp)
+{
+  int old_fd = vrrp->fd;
+  list p = conf_data->vrrp;
+  vrrp_rt *vrrp_ptr;
+  element e;
+
+  /* close the desc & open a new one */
+  close_vrrp_socket(vrrp);
+  if (vrrp->auth_type == VRRP_AUTH_AH)
+    vrrp->fd = open_vrrp_socket(IPPROTO_IPSEC_AH, IF_INDEX(vrrp->ifp));
+  else
+    vrrp->fd = open_vrrp_socket(IPPROTO_VRRP, IF_INDEX(vrrp->ifp));
+
+  /* Sync the other desc */
+  for (e = LIST_HEAD(p); e; ELEMENT_NEXT(e)) {
+    vrrp_ptr = ELEMENT_DATA(e);
+    if (vrrp_ptr->fd == old_fd)
+      vrrp_ptr->fd = vrrp->fd;
+  }
+}
 
 /* handle terminate state */
 void shutdown_vrrp_instances(void)
 {
   list l = conf_data->vrrp;
   element e;
-  vrrp_instance *vrrp;
+  vrrp_rt *vrrp;
 
   for (e = LIST_HEAD(l); e; ELEMENT_NEXT(e)) {
     vrrp = ELEMENT_DATA(e);
 
     /* remove VIPs */
-    if (vrrp->vsrv->state == VRRP_STATE_MAST)
-      vrrp_restore_interface(vrrp->vsrv, 1);
+    if (vrrp->state == VRRP_STATE_MAST ||
+        vrrp->state == VRRP_STATE_DUMMY_MAST)
+      vrrp_restore_interface(vrrp, 1);
+
+    /* Stop stalled syncd */
+    if (vrrp->lvs_syncd_if)
+      ipvs_syncd_cmd(IPVS_STOPDAEMON, NULL, 0);
   }
 }
 
 /* complete vrrp structure */
-static int vrrp_complete_instance(vrrp_rt *vsrv)
+static int vrrp_complete_instance(vrrp_rt *vrrp)
 {
-  vrrp_if *vif = vsrv->vif;
-
   /* complete the VMAC address */
-  vsrv->hwaddr[0] = 0x00;
-  vsrv->hwaddr[1] = 0x00;
-  vsrv->hwaddr[2] = 0x5E;
-  vsrv->hwaddr[3] = 0x00;
-  vsrv->hwaddr[4] = 0x01;
-  vsrv->hwaddr[5] = vsrv->vrid;
-
-  /* get the ip address */
-  vif->ipaddr = ifname_to_ip(vif->ifname);
-  if (!vif->ipaddr) {
-    syslog(LOG_INFO, "VRRP Error : no interface found : %s !\n", vif->ifname);
-    return 0;
-  }
-  /* get the hwaddr */
-  if (hwaddr_get(vif->ifname, vif->hwaddr, sizeof(vif->hwaddr))) {
-    syslog(LOG_INFO, "VRRP Error : Unreadable MAC"
-                     "address for interface : %s !\n", vif->ifname);
-    return 0;
-  }
-
-  vsrv->state = VRRP_STATE_INIT;
-  if (!vsrv->adver_int) vsrv->adver_int = VRRP_ADVER_DFL * TIMER_HZ;
-  if (!vsrv->priority) vsrv->priority = VRRP_PRIO_DFL;
-  if (!vsrv->preempt) vsrv->preempt = VRRP_PREEMPT_DFL;
-
-  return(chk_min_cfg(vsrv));
+  vrrp->hwaddr[0] = 0x00;
+  vrrp->hwaddr[1] = 0x00;
+  vrrp->hwaddr[2] = 0x5E;
+  vrrp->hwaddr[3] = 0x00;
+  vrrp->hwaddr[4] = 0x01;
+  vrrp->hwaddr[5] = vrrp->vrid;
+
+  vrrp->state                           = VRRP_STATE_INIT;
+  if (!vrrp->adver_int) vrrp->adver_int = VRRP_ADVER_DFL * TIMER_HZ;
+  if (!vrrp->priority) vrrp->priority   = VRRP_PRIO_DFL;
+  if (!vrrp->preempt) vrrp->preempt     = VRRP_PREEMPT_DFL;
+
+  return(chk_min_cfg(vrrp));
 }
 
 void vrrp_complete_init(void)
 {
   list l = conf_data->vrrp;
   element e;
-  vrrp_instance *vrrp;
+  vrrp_rt *vrrp;
 
   for (e = LIST_HEAD(l); e; ELEMENT_NEXT(e)) {
     vrrp = ELEMENT_DATA(e);
-    vrrp_complete_instance(vrrp->vsrv);
+    vrrp_complete_instance(vrrp);
   }
 }
diff --git a/vrrp.h b/vrrp.h
index 5de4bce..9cb8c67 100644 (file)
--- a/vrrp.h
+++ b/vrrp.h
@@ -6,7 +6,7 @@
  *
  * Part:        vrrp.c program include file.
  *
- * Version:     $Id: vrrp.h,v 0.5.3 2002/02/24 23:50:11 acassen Exp $
+ * Version:     $Id: vrrp.h,v 0.5.5 2002/04/10 02:34:23 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *              Based on the Jerome Etienne, <jetienne@arobas.net> code.
 /* local include */
 #include "vrrp_ipaddress.h"
 #include "vrrp_ipsecah.h"
+#include "vrrp_if.h"
 #include "timer.h"
 #include "utils.h"
 
-
 /* Default dir to notify file */
 #define VRRP_NOTIFY_DFL "/etc/init.d"
 
@@ -74,31 +74,21 @@ typedef struct {    /* rfc2338.5.1 */
 #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 interface -- rfc2338.6.1.1 */
 typedef struct {
-       int             auth_type;      /* authentification type. VRRP_AUTH_* */
-       uint8_t         auth_data[8];   /* authentification data */
-
-       uint32_t        ipaddr;         /* the address of the interface */
-       char            hwaddr[6];      /* hardcoded for ethernet */
-       char            *ifname;        /* the device name for this ipaddr */
-       /*
-        * To have my own ip_id creates collision with kernel ip->id
-        * but it should be ok because the packets are unlikely to be
-        * fragmented (they are non routable and small)
-        * This packet isnt routed, i can check the outgoing MTU
-        * to warn the user only if the outoing mtu is too small
-        */
-       int             ip_id;
-} vrrp_if;
-
-typedef struct {
-       uint32_t        addr;           /* the ip address */
-       int             deletable;      /* TRUE if one of my primary addr */
+       uint32_t        addr;   /* the ip address */
+       int             set;    /* TRUE if addr is set */
 } vip_addr;
 
 /* parameters per virtual router -- rfc2338.6.1.2 */
-typedef struct {
+typedef struct _vrrp_rt {
+       char    *iname;         /* Instance Name */
+       char    *isync;         /* Instance Name to be sync with */
+       interface *ifp;         /* Interface we belong to */
+       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 */
@@ -111,29 +101,43 @@ typedef struct {
        int     wantstate;      /* user explicitly wants a state (back/mast) */
        int     fd;             /* the socket descriptor */
 
-        int     debug;          /* Debug level 0-4 */
-        int     notify_exec;
-        char    notify_file[FILENAME_MAX];
+       int     debug;          /* Debug level 0-4 */
+       int     notify_exec;
+       char    notify_file[FILENAME_MAX];
 
        /* rfc2336.6.2 */
        uint32_t        ms_down_timer;
        struct timeval  sands;
 
+       /* Authentication data */
+       int             auth_type;      /* authentification type. VRRP_AUTH_* */
+       uint8_t         auth_data[8];   /* authentification data */
+
+       /*
+        * To have my own ip_id creates collision with kernel ip->id
+        * but it should be ok because the packets are unlikely to be
+        * fragmented (they are non routable and small)
+        * This packet isnt routed, i can check the outgoing MTU
+        * to warn the user only if the outoing mtu is too small
+        */
+       int             ip_id;
+
        /* IPSEC AH counter def --rfc2402.3.3.2 */
        seq_counter *ipsecah_counter;
-
-       /* interface parameters */
-       vrrp_if *vif;
 } vrrp_rt;
 
 /* VRRP state machine -- rfc2338.6.4 */
-#define VRRP_DISPATCHER        0       /* internal */
-#define VRRP_STATE_INIT                1       /* rfc2338.6.4.1 */
-#define VRRP_STATE_BACK                2       /* rfc2338.6.4.2 */
-#define VRRP_STATE_MAST                3       /* rfc2338.6.4.3 */
-#define VRRP_STATE_GOTO_MASTER 4       /* internal */
-#define VRRP_STATE_LEAVE_MASTER        5       /* internal */
-#define VRRP_STATE_FAULT       99      /* internal */
+#define VRRP_DISPATCHER                0       /* internal */
+#define VRRP_STATE_INIT                        1       /* rfc2338.6.4.1 */
+#define VRRP_STATE_BACK                        2       /* rfc2338.6.4.2 */
+#define VRRP_STATE_MAST                        3       /* rfc2338.6.4.3 */
+#define VRRP_STATE_GOTO_MASTER         4       /* internal */
+#define VRRP_STATE_LEAVE_MASTER                5       /* internal */
+#define VRRP_STATE_GOTO_DUMMY_MAST     96      /* internal */
+#define VRRP_STATE_DUMMY_MAST          97      /* internal */
+#define VRRP_STATE_GOTO_FAULT          98      /* internal */
+#define VRRP_STATE_FAULT               99      /* internal */
+#define VRRP_MCAST_RETRY               10      /* internal */
 
 /* VRRP packet handling */
 #define VRRP_PACKET_OK       0
@@ -158,6 +162,16 @@ typedef struct {
 #define VRRP_MAX(a, b) ((a) > (b)?(a):(b))
 
 /* prototypes */
+extern int open_vrrp_socket(const int proto, const int index);
+extern void new_vrrp_socket(vrrp_rt *vrrp);
+extern void close_vrrp_socket(vrrp_rt *vrrp);
+extern void vrrp_send_gratuitous_arp(vrrp_rt *vrrp);
+extern int vrrp_state_fault_rx(vrrp_rt *vrrp, char *buf, int buflen);
+extern int vrrp_state_master_rx(vrrp_rt *vrrp, char *buf, int buflen);
+extern void vrrp_state_master_tx(vrrp_rt *vrrp, const int prio);
+extern void vrrp_state_backup(vrrp_rt *vrrp, char *buf, int buflen);
+extern void vrrp_state_goto_master(vrrp_rt *vrrp);
+extern void vrrp_state_leave_master(vrrp_rt *vrrp);
 extern int vrrp_ipsecah_len(void);
 extern void vrrp_complete_init(void);
 extern void shutdown_vrrp_instances(void);
diff --git a/vrrp_if.c b/vrrp_if.c
new file mode 100644 (file)
index 0000000..46e367f
--- /dev/null
+++ b/vrrp_if.c
@@ -0,0 +1,299 @@
+/*
+ * 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:        Interfaces manipulation.
+ *
+ * Version:     $Id: vrrp_if.c,v 0.5.5 2002/04/10 02:34:23 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.
+ */
+
+/* global include */
+#include <unistd.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/ioctl.h>
+#include <netinet/ip.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <syslog.h>
+#include <ctype.h>
+#ifdef use_linux_libc5
+  #include <linux/if_arp.h>
+  #include <linux/if_ether.h>
+#endif
+#include <stdlib.h>
+#include <stdio.h>
+
+/* local include */
+#include "scheduler.h"
+#include "data.h"
+#include "vrrp_if.h"
+#include "vrrp_netlink.h"
+#include "memory.h"
+#include "utils.h"
+
+/* Global vars */
+extern thread_master *master;
+extern data *conf_data;
+static struct ifreq ifr;
+
+/* Helper functions */
+/* Return interface from interface index */
+interface *if_get_by_ifindex(const int ifindex)
+{
+  interface *ifp;
+  element e;
+
+  for (e = LIST_HEAD(if_queue); e; ELEMENT_NEXT(e)) {
+    ifp = ELEMENT_DATA(e);
+    if (ifp->ifindex == ifindex)
+      return ifp;
+  }
+  return NULL;
+}
+
+interface *if_get_by_ifname(const char *ifname)
+{
+  interface *ifp;
+  element e;
+
+  for (e = LIST_HEAD(if_queue); e; ELEMENT_NEXT(e)) {
+    ifp = ELEMENT_DATA(e);
+    if (!strcmp(ifp->ifname, ifname))
+      return ifp;
+  }
+  return NULL;
+}
+
+/* MII Transceiver Registers poller functions */
+static int if_mii_read(const int fd, const int phy_id, int location)
+{
+  uint16_t *data = (uint16_t *)(&ifr.ifr_data);
+
+  data[0] = phy_id;
+  data[1] = location;
+
+  if (ioctl(fd, SIOCGMIIREG, &ifr) < 0) {
+    syslog(LOG_ERR, "SIOCGMIIREG on %s failed: %s"
+                  , ifr.ifr_name
+                  , strerror(errno));
+    return -1;
+  }
+  return data[3];
+}
+
+/*
+static void if_mii_dump(const uint16_t mii_regs[32], unsigned phy_id)
+{
+  int mii_reg;
+
+  printf(" MII PHY #%d transceiver registers:\n", phy_id);
+  for (mii_reg = 0; mii_reg < 32; mii_reg++)
+    printf("%s %4.4x", (mii_reg % 8) == 0 ? "\n ":"", mii_regs[mii_reg]);
+}
+*/
+
+static int if_mii_status(const int fd)
+{
+  uint16_t *data = (uint16_t *)(&ifr.ifr_data);
+  unsigned phy_id = data[0];
+  uint16_t mii_regs[32];
+  int mii_reg;
+  uint16_t bmsr, new_bmsr;
+
+  /* Reset MII registers */
+  memset(mii_regs, 0, sizeof(mii_regs));
+
+  for (mii_reg = 0; mii_reg < 32; mii_reg++)
+    mii_regs[mii_reg] = if_mii_read(fd, phy_id, mii_reg);
+
+// if_mii_dump(mii_regs, phy_id);
+
+  if (mii_regs[0] == 0xffff) {
+    syslog(LOG_ERR, "No MII transceiver present for %s !!!"
+                  , ifr.ifr_name);
+    return -1;
+  }
+
+  bmsr = mii_regs[1];
+
+  /*
+   * For Basic Mode Status Register (BMSR).
+   * Sticky field (Link established & Jabber detected), we need to read
+   * a second time the BMSR to get current status.
+   */
+  new_bmsr = if_mii_read(fd, phy_id, 1);
+
+// printf(" \nBasic Mode Status Register 0x%4.4x ... 0x%4.4x\n", bmsr, new_bmsr);
+
+  if (bmsr & 0x0004)
+    return LINK_UP;
+  else if (new_bmsr & 0x0004)
+    return LINK_UP;
+  else
+    return LINK_DOWN;
+}
+
+int if_mii_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));
+  if (ioctl(fd, SIOCGMIIPHY, &ifr) < 0) {
+    close(fd);
+    return -1;
+  }
+
+  /* Dump the MII transceiver */
+  status = if_mii_status(fd);
+  close(fd);
+  return status;
+}
+
+/* Interfaces lookup */
+static void free_if(void *data)
+{
+  FREE(data);
+}
+void dump_if(void *data)
+{
+  interface *ifp = data;
+
+  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));
+
+  /* FIXME: Harcoded for ethernet */
+  if (ifp->hw_type == ARPHRD_ETHER)
+    syslog(LOG_INFO, " MAC = %.2x:%.2x:%.2x:%.2x:%.2x:%.2x"
+                   , ifp->hw_addr[0], ifp->hw_addr[1], ifp->hw_addr[2]
+                   , ifp->hw_addr[3], ifp->hw_addr[4], ifp->hw_addr[5]);
+
+  if (ifp->flags & IFF_UP)
+    syslog(LOG_INFO, " is UP");
+
+  if (ifp->flags & IFF_RUNNING)
+    syslog(LOG_INFO, " is RUNNING");
+
+  if (!(ifp->flags & IFF_UP) && !(ifp->flags & IFF_RUNNING))
+    syslog(LOG_INFO, " is DOWN");
+
+  syslog(LOG_INFO, " MTU = %d", ifp->mtu);
+
+  switch (ifp->hw_type) {
+    case ARPHRD_LOOPBACK:
+      syslog(LOG_INFO, " HW Type = LOOPBACK");
+      break;
+    case ARPHRD_ETHER:
+      syslog(LOG_INFO, " HW Type = ETHERNET");
+      break;
+    default:
+      syslog(LOG_INFO, " HW Type = UNKNOWN");
+      break;
+  }
+
+  /* MII registers supported ? */
+  if (IF_MII_SUPPORTED(ifp))
+    syslog(LOG_INFO, " NIC support MII regs");
+}
+
+static void init_if_queue(void)
+{
+  if_queue = alloc_list(free_if, dump_if);
+}
+void if_add_queue(interface *ifp)
+{
+  list_add(if_queue, ifp);
+}
+
+static void init_if_mii(void)
+{
+  interface *ifp;
+  element e;
+  int status;
+
+  for (e = LIST_HEAD(if_queue); e; ELEMENT_NEXT(e)) {
+    ifp = ELEMENT_DATA(e);
+    status = if_mii_probe(ifp->ifname);
+    if (status < 0)
+      ifp->mii = 0;
+    else {
+      ifp->mii = 1;
+      ifp->mii_linkbeat = (status)?1:0;
+    }
+  }
+}
+
+static void if_mii_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;
+    }
+  }
+}
+
+int if_mii_linkbeat(const interface *ifp)
+{
+  if (IF_MII_SUPPORTED(ifp))
+    return IF_MII_LINKBEAT(ifp);
+  return 1;
+}
+
+/* Our interface Heartbeat thread */
+int if_monitor_thread(thread *thread)
+{
+  /* If present, refresh link beat status from MII BMSR */
+  if_mii_refresh();
+
+  /* Register new monitor thread */
+  thread_add_timer(master, if_monitor_thread
+                         , NULL
+                         , POLLING_DELAY);
+  return 0;
+}
+
+/* Interface queue helpers*/
+void free_interface_queue(void)
+{
+  if (!LIST_ISEMPTY(if_queue))
+    free_list(if_queue);
+}
+void init_interface_queue(void)
+{
+  init_if_queue();
+  netlink_interface_lookup();
+  init_if_mii();
+  kernel_netlink_init();
+//  dump_list(if_queue);
+
+  /* Register NIC Heartbeat monitoring thread */
+  thread_add_timer(master, if_monitor_thread
+                         , NULL
+                         , POLLING_DELAY);
+}
diff --git a/vrrp_if.h b/vrrp_if.h
new file mode 100644 (file)
index 0000000..89b7bb4
--- /dev/null
+++ b/vrrp_if.h
@@ -0,0 +1,91 @@
+/*
+ * 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_if.c include file.
+ *
+ * Version:     $Id: vrrp_if.h,v 0.5.5 2002/04/10 02:34:23 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_IF_H
+#define _VRRP_IF_H
+
+/* global includes */
+#include <net/if.h>
+
+/* local includes */
+#include "scheduler.h"
+#include "list.h"
+
+/* types definition */
+#ifndef SIOCGMIIPHY
+  #define SIOCGMIIPHY (SIOCDEVPRIVATE)            /* Get the PHY in use. */
+  #define SIOCGMIIREG (SIOCDEVPRIVATE+1)          /* Read a PHY register. */
+  #define SIOCSMIIREG (SIOCDEVPRIVATE+2)          /* Write a PHY register. */
+  #define SIOCGPARAMS (SIOCDEVPRIVATE+3)          /* Read operational parameters. */
+  #define SIOCSPARAMS (SIOCDEVPRIVATE+4)          /* Set operational parameters. */
+#endif
+#define LINK_UP   1
+#define LINK_DOWN 0
+#define IF_NAMESIZ    20 /* Max interface lenght size */
+#define IF_HWADDR_MAX 20 /* Max MAC address length size */
+#define ARPHRD_ETHER 1
+#define ARPHRD_LOOPBACK 772
+#define POLLING_DELAY 1
+
+/* 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 */
+} interface;
+
+/* Global interface queue */
+list if_queue;
+
+/* Macros */
+#define IF_NAME(X) ((X)->ifname)
+#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_ISUP(X) (((X)->flags & IFF_UP)      && \
+                    ((X)->flags & IFF_RUNNING) && \
+                    if_mii_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_mii_probe(const char *ifname);
+extern void if_add_queue(interface *ifp);
+extern int if_monitor_thread(thread *thread);
+extern void init_interface_queue(void);
+extern void free_interface_queue(void);
+extern void dump_if(void *data);
+
+#endif
index fa8700a..1d937ad 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Part:        NETLINK IPv4 address manipulation.
  *
- * Version:     $Id: vrrp_ipaddress.c,v 0.5.3 2002/02/24 23:50:11 acassen Exp $
+ * Version:     $Id: vrrp_ipaddress.c,v 0.5.5 2002/04/10 02:34:23 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
 #include "vrrp_ipaddress.h"
 #include "vrrp_netlink.h"
 
+/* Check if interface is UP */
+
+
+/* Add/Delete IP address to a specific interface */
 int netlink_address_ipv4(int ifindex, uint32_t addr, int cmd)
 {
   struct nl_handle nlh;
+  int status = 1;
   struct {
     struct nlmsghdr n;
     struct ifaddrmsg ifa;
@@ -49,10 +54,9 @@ int netlink_address_ipv4(int ifindex, uint32_t addr, int cmd)
     return -1;
 
   if (netlink_talk(&nlh, &req.n) < 0)
-    return -1;
-  
+    status = -1;
+
   /* to close the clocket */
   netlink_close(&nlh);
-
-  return(0);
+  return status;
 }
index b48fa0a..55d0f74 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Part:        vrrp_ipaddress.c include file.
  *
- * Version:     $Id: vrrp_ipaddress.h,v 0.5.3 2002/02/24 23:50:11 acassen Exp $
+ * Version:     $Id: vrrp_ipaddress.h,v 0.5.5 2002/04/10 02:34:23 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
index dbe6855..1fc60d1 100644 (file)
@@ -7,7 +7,7 @@
  *              authentication data encryption using HMAC MD5 according to
  *              RFCs 2085 & 2104.
  *
- * Version:     $Id: vrrp_ipsecah.c,v 0.5.3 2002/02/24 23:50:11 acassen Exp $
+ * Version:     $Id: vrrp_ipsecah.c,v 0.5.5 2002/04/10 02:34:23 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
 #include <openssl/md5.h>
 
 /* hmac_md5 computation according to the RFCs 2085 & 2104 */
-void hmac_md5(unsigned char *buffer,int buffer_len,
-              unsigned char *key,int key_len,unsigned char *digest)
+void hmac_md5(unsigned char *buffer, int buffer_len
+                                   , unsigned char *key
+                                   , int key_len
+                                   , unsigned char *digest)
 {
   MD5_CTX context;
   unsigned char k_ipad[65]; /* inner padding - key XORd with ipad */
index 82a5a92..fe21019 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Part:        vrrp_ipsecah.c include file.
  * 
- * Version:     $Id: vrrp_ipsecah.h,v 0.5.3 2002/02/24 23:50:11 acassen Exp $
+ * Version:     $Id: vrrp_ipsecah.h,v 0.5.5 2002/04/10 02:34:23 acassen Exp $
  * 
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *              
index f8803d1..cc08488 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Part:        NETLINK kernel command channel.
  *
- * Version:     $Id: vrrp_netlink.c,v 0.5.3 2002/02/24 23:50:11 acassen Exp $
+ * Version:     $Id: vrrp_netlink.c,v 0.5.5 2002/04/10 02:34:23 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
@@ -20,7 +20,7 @@
  *              2 of the License, or (at your option) any later version.
  */
 
-/* local include */
+/* global include */
 #include <stdio.h>
 #include <stdlib.h>
 #include <unistd.h>
 #include <time.h>
 #include <sys/uio.h>
 
+/* local include */
 #include "vrrp_netlink.h"
+#include "vrrp_if.h"
+#include "memory.h"
+#include "scheduler.h"
+#include "utils.h"
+
+/* Global vars */
+extern thread_master *master;
 
 /* Create a socket to netlink interface */
 int netlink_socket(struct nl_handle *nl, unsigned long groups)
@@ -116,6 +124,15 @@ int addattr_l(struct nlmsghdr *n, int maxlen, int type, void *data, int alen)
   return 0;
 }
 
+static void parse_rtattr(struct rtattr **tb, int max, struct rtattr *rta, int len)
+{
+  while (RTA_OK(rta, len)) {
+    if (rta->rta_type <= max)
+      tb[rta->rta_type] = rta;
+    rta = RTA_NEXT(rta, len);
+  }
+}
+
 /* Our netlink parser */
 static int netlink_parse_info(int (*filter) (struct sockaddr_nl *, struct nlmsghdr *),
                               struct nl_handle *nl)
@@ -227,3 +244,268 @@ int netlink_talk(struct nl_handle *nl, struct nlmsghdr *n)
   status = netlink_parse_info(netlink_talk_filter, nl);
   return status;
 }
+
+/* Fetch a specific type information from netlink kernel */
+static int netlink_request(struct nl_handle *nl, int family, int type)
+{
+  int status;
+  struct sockaddr_nl snl;
+  struct {
+    struct nlmsghdr nlh;
+    struct rtgenmsg g;
+  } req;
+
+  /* Cleanup the room */
+  memset(&snl, 0, sizeof(snl));
+  snl.nl_family = AF_NETLINK;
+
+  req.nlh.nlmsg_len = sizeof(req);
+  req.nlh.nlmsg_type = type;
+  req.nlh.nlmsg_flags = NLM_F_ROOT | NLM_F_MATCH | NLM_F_REQUEST;
+  req.nlh.nlmsg_pid = 0;
+  req.nlh.nlmsg_seq = ++nl->seq;
+  req.g.rtgen_family = family;
+
+  status = sendto(nl->fd, (void *) &req
+                        , sizeof(req)
+                        , 0
+                        , (struct sockaddr *) &snl
+                        , sizeof(snl));
+  if (status < 0) {
+    syslog(LOG_INFO, "Netlink: sendto() failed: %s"
+                   , strerror(errno));
+    return -1;
+  }
+  return 0;
+}
+
+/* Netlink interface link lookup filter */
+static int netlink_if_link_filter(struct sockaddr_nl *snl, struct nlmsghdr *h)
+{
+  struct ifinfomsg *ifi;
+  struct rtattr *tb[IFLA_MAX + 1];
+  interface *ifp;
+  int i, len;
+  char *name;
+
+  ifi = NLMSG_DATA(h);
+
+  if (h->nlmsg_type != RTM_NEWLINK)
+    return 0;
+
+  len = h->nlmsg_len - NLMSG_LENGTH(sizeof(struct ifinfomsg));
+  if (len < 0)
+    return -1;
+
+  /* Interface name lookup */
+  memset(tb, 0, sizeof(tb));
+  parse_rtattr(tb, IFLA_MAX, IFLA_RTA(ifi), len);
+  if (tb[IFLA_IFNAME] == NULL)
+    return -1;
+  name = (char *)RTA_DATA(tb[IFLA_IFNAME]);
+
+  /* Return if loopback */
+  if (ifi->ifi_type == ARPHRD_LOOPBACK)
+    return 0;
+
+  /* Fill the interface structure */
+  ifp = (interface *)MALLOC(sizeof(interface));
+  memcpy(ifp->ifname, name, strlen(name));
+  ifp->ifindex = ifi->ifi_index;
+  ifp->flags = ifi->ifi_flags;
+  ifp->mtu = *(int *)RTA_DATA(tb[IFLA_MTU]);
+  ifp->hw_type = ifi->ifi_type;
+
+  if (tb[IFLA_ADDRESS]) {
+    int hw_addr_len = RTA_PAYLOAD(tb[IFLA_ADDRESS]);
+
+    if (hw_addr_len > IF_HWADDR_MAX)
+      syslog(LOG_ERR, "MAC address for %s is too large: %d"
+                    , name
+                    , hw_addr_len);
+    else {
+      ifp->hw_addr_len = hw_addr_len;
+      memcpy(ifp->hw_addr, RTA_DATA(tb[IFLA_ADDRESS]), hw_addr_len);
+      for (i = 0; i < hw_addr_len; i++)
+        if (ifp->hw_addr[i] != 0)
+          break;
+      if (i == hw_addr_len)
+        ifp->hw_addr_len = 0;
+      else
+        ifp->hw_addr_len = hw_addr_len;
+    }
+  }
+
+  /* Queue this new interface */
+  if_add_queue(ifp);
+  return 0;
+}
+
+/*
+ * Netlink interface address lookup filter
+ * We need to handle multiple primary address and
+ * multiple secondary address to the same interface.
+ */
+static int netlink_if_address_filter(struct sockaddr_nl *snl, struct nlmsghdr *h)
+{
+  struct ifaddrmsg *ifa;
+  struct rtattr *tb[IFA_MAX + 1];
+  interface *ifp;
+  int len;
+
+  ifa = NLMSG_DATA(h);
+
+  /* Only IPV4 are valid us */
+  if (ifa->ifa_family != AF_INET)
+    return 0;
+
+  if (h->nlmsg_type != RTM_NEWADDR &&
+      h->nlmsg_type != RTM_DELADDR)
+    return 0;
+
+  len = h->nlmsg_len - NLMSG_LENGTH(sizeof(struct ifaddrmsg));
+  if (len < 0)
+    return -1;
+
+  memset(tb, 0, sizeof(tb));
+  parse_rtattr(tb, IFA_MAX, IFA_RTA(ifa), len);
+
+  /* Fetch interface */
+  ifp = if_get_by_ifindex(ifa->ifa_index);
+  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]);
+    }
+  } else {
+    if (tb[IFA_ADDRESS])
+      ifp->address = *(uint32_t *)RTA_DATA(tb[IFA_ADDRESS]);
+  }
+
+  return 0;
+}
+
+/* Interface lookup bootstrap function */
+int netlink_interface_lookup(void)
+{
+  struct nl_handle nlh;
+  int status = 0;
+
+  if (netlink_socket(&nlh, 0) < 0)
+    return -1;
+
+  /* Interface lookup */
+  if (netlink_request(&nlh, AF_PACKET, RTM_GETLINK) < 0) {
+    status = -1;
+    goto end;
+  }
+  status = netlink_parse_info(netlink_if_link_filter, &nlh); 
+
+  /* Address lookup */
+  if (netlink_request(&nlh, AF_INET, RTM_GETADDR) < 0) {
+    status = -1;
+    goto end;
+  }
+  status = netlink_parse_info(netlink_if_address_filter, &nlh); 
+  
+end:
+  netlink_close(&nlh);
+  return status;
+}
+
+/* Netlink flag Link update */
+static int netlink_reflect_filter(struct sockaddr_nl *snl, struct nlmsghdr *h)
+{
+  struct ifinfomsg *ifi;
+  struct rtattr *tb[IFLA_MAX + 1];
+  interface *ifp;
+  int len;
+
+  ifi = NLMSG_DATA(h);
+  if ( !(h->nlmsg_type == RTM_NEWLINK || h->nlmsg_type == RTM_DELLINK))
+    return 0;
+
+  len = h->nlmsg_len - NLMSG_LENGTH(sizeof(struct ifinfomsg));
+  if (len < 0)
+    return -1;
+
+  /* Interface name lookup */
+  memset(tb, 0, sizeof(tb));
+  parse_rtattr(tb, IFLA_MAX, IFLA_RTA(ifi), len);
+  if (tb[IFLA_IFNAME] == NULL)
+    return -1;
+
+  /* ignore loopback device */
+  if (ifi->ifi_type == ARPHRD_LOOPBACK)
+    return 0;
+
+  /* find the interface */
+  ifp = if_get_by_ifindex(ifi->ifi_index);
+  if (!ifp)
+    return -1;
+
+  /* Update flags */
+  ifp->flags = ifi->ifi_flags;
+
+  return 0;
+}
+
+/* Netlink kernel message reflection */
+static int netlink_broadcast_filter(struct sockaddr_nl *snl, struct nlmsghdr *h)
+{
+  switch (h->nlmsg_type) {
+    case RTM_NEWLINK:
+    case RTM_DELLINK:
+      return netlink_reflect_filter(snl, h);
+      break;
+    case RTM_NEWADDR:
+    case RTM_DELADDR:
+//      return netlink_if_address_filter(snl, h);
+      break;
+    default:
+      syslog(LOG_INFO, "Kernel is reflecting an unknown netlink nlmsg_type: %d"
+                     , h->nlmsg_type);
+      break;
+  }
+  return 0;
+}
+
+int kernel_netlink(thread *thread)
+{
+  int status = 0;
+
+  if (thread->type != THREAD_READ_TIMEOUT)
+    status = netlink_parse_info(netlink_broadcast_filter, &nl_kernel);
+  thread_add_read(master, kernel_netlink
+                        , NULL
+                        , nl_kernel.fd
+                        , NETLINK_TIMER);
+  return 0;
+}
+
+void kernel_netlink_init(void)
+{
+  unsigned long groups;
+
+  groups = RTMGRP_LINK | RTMGRP_IPV4_IFADDR;
+  netlink_socket(&nl_kernel, groups);
+
+  if (nl_kernel.fd > 0) {
+    syslog(LOG_INFO, "Registering Kernel netlink reflector");
+    thread_add_read(master, kernel_netlink
+                          , NULL
+                          , nl_kernel.fd
+                          , NETLINK_TIMER);
+  }
+}
index ecc053a..7e4f7c7 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Part:        vrrp_netlink.c include file.
  *
- * Version:     $Id: vrrp_netlink.h,v 0.5.3 2002/02/24 23:50:11 acassen Exp $
+ * Version:     $Id: vrrp_netlink.h,v 0.5.5 2002/04/10 02:34:23 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
@@ -40,10 +40,19 @@ struct nl_handle {
   __u32 seq;
 };
 
+/* Define types */
+#define NETLINK_TIMER 30
+
+/* Our global netlink reflection handler */
+struct nl_handle nl_kernel;
+
 /* prototypes */
 extern int addattr_l(struct nlmsghdr *n, int maxlen, int type, void *data, int alen);
 extern int netlink_socket(struct nl_handle *nl, unsigned long groups);
 extern int netlink_close(struct nl_handle *nl);
 extern int netlink_talk (struct nl_handle *nl, struct nlmsghdr *n);
+extern int netlink_interface_lookup(void);
+extern int netlink_interface_refresh(void);
+extern void kernel_netlink_init(void);
 
 #endif
index 79ea6b2..b9c9214 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Part:        Sheduling framework for vrrp code.
  *
- * Version:     $Id: vrrp_scheduler.c,v 0.5.3 2002/02/24 23:50:11 acassen Exp $
+ * Version:     $Id: vrrp_scheduler.c,v 0.5.5 2002/04/10 02:34:23 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 "ipvswrapper.h"
 #include "memory.h"
 #include "list.h"
+#include "data.h"
 
 extern thread_master *master;
 extern data *conf_data;
@@ -35,46 +39,54 @@ extern data *conf_data;
  */
 static void vrrp_init_state(list l)
 {
-  vrrp_instance *vrrp;
+  vrrp_rt *vrrp;
   element e;
 
   for (e = LIST_HEAD(l); e; ELEMENT_NEXT(e)) {
     vrrp = ELEMENT_DATA(e);
 
-    if (vrrp->vsrv->priority == VRRP_PRIO_OWNER ||
-        vrrp->vsrv->wantstate == VRRP_STATE_MAST) {
-      vrrp->vsrv->state = VRRP_STATE_GOTO_MASTER;
+    if (vrrp->priority == VRRP_PRIO_OWNER ||
+        vrrp->wantstate == VRRP_STATE_MAST) {
+      vrrp->state = VRRP_STATE_GOTO_MASTER;
     } else {
-      vrrp->vsrv->ms_down_timer = 3 * vrrp->vsrv->adver_int
-                                      + VRRP_TIMER_SKEW(vrrp->vsrv);
-      vrrp->vsrv->state = VRRP_STATE_BACK;
+      vrrp->ms_down_timer = 3 * vrrp->adver_int
+                              + VRRP_TIMER_SKEW(vrrp);
+      /* Check if sync daemon handling is needed */
+      if (vrrp->lvs_syncd_if)
+        ipvs_syncd_cmd(IPVS_STARTDAEMON, vrrp->lvs_syncd_if
+                                       , IPVS_BACKUP);
+      vrrp->state = VRRP_STATE_BACK;
     }
   }
 }
 
-static void vrrp_init_instance_sands(vrrp_instance *vrrp)
+static void vrrp_init_instance_sands(vrrp_rt *vrrp)
 {
   TIMEVAL timer;
 
   timer = timer_now();
 
-  if (vrrp->vsrv->state == VRRP_STATE_BACK) {
-    vrrp->vsrv->sands.tv_sec = timer.tv_sec +
-                               vrrp->vsrv->ms_down_timer / TIMER_HZ;
-    vrrp->vsrv->sands.tv_usec = timer.tv_usec +
-                                vrrp->vsrv->ms_down_timer % TIMER_HZ;
+  if (vrrp->state == VRRP_STATE_BACK ||
+      vrrp->state == VRRP_STATE_FAULT) {
+    vrrp->sands.tv_sec = timer.tv_sec +
+                         vrrp->ms_down_timer / TIMER_HZ;
+    vrrp->sands.tv_usec = timer.tv_usec +
+                          vrrp->ms_down_timer % TIMER_HZ;
   }
-  if (vrrp->vsrv->state == VRRP_STATE_GOTO_MASTER ||
-      vrrp->vsrv->state == VRRP_STATE_MAST) {
-    vrrp->vsrv->sands.tv_sec = timer.tv_sec +
-                               vrrp->vsrv->adver_int / TIMER_HZ;
-    vrrp->vsrv->sands.tv_usec = timer.tv_usec;
+  if (vrrp->state == VRRP_STATE_GOTO_MASTER     ||
+      vrrp->state == VRRP_STATE_GOTO_DUMMY_MAST ||
+      vrrp->state == VRRP_STATE_MAST            ||
+      vrrp->state == VRRP_STATE_DUMMY_MAST      ||
+      vrrp->state == VRRP_STATE_GOTO_FAULT) {
+    vrrp->sands.tv_sec = timer.tv_sec +
+                         vrrp->adver_int / TIMER_HZ;
+    vrrp->sands.tv_usec = timer.tv_usec;
   }
 }
 
 static void vrrp_init_sands(list l)
 {
-  vrrp_instance *vrrp;
+  vrrp_rt *vrrp;
   element e;
 
   for (e = LIST_HEAD(l); e; ELEMENT_NEXT(e)) {
@@ -86,7 +98,7 @@ static void vrrp_init_sands(list l)
 /* Timer functions */
 static TIMEVAL vrrp_compute_timer(const int fd)
 {
-  vrrp_instance *vrrp;
+  vrrp_rt *vrrp;
   TIMEVAL timer;
   element e;
   list l = conf_data->vrrp;
@@ -96,10 +108,10 @@ static TIMEVAL vrrp_compute_timer(const int fd)
 
   for (e = LIST_HEAD(l); e; ELEMENT_NEXT(e)) {
     vrrp = ELEMENT_DATA(e);
-    if (vrrp->vsrv->fd == fd) {
-      if (timer_cmp(vrrp->vsrv->sands, timer) < 0 ||
+    if (vrrp->fd == fd) {
+      if (timer_cmp(vrrp->sands, timer) < 0 ||
           TIMER_ISNULL(timer))
-        timer = timer_dup(vrrp->vsrv->sands);
+        timer = timer_dup(vrrp->sands);
     }
   }
 
@@ -120,7 +132,7 @@ static long vrrp_timer_fd(const int fd)
 
 static int vrrp_timer_vrid_timeout(const int fd)
 {
-  vrrp_instance *vrrp;
+  vrrp_rt *vrrp;
   list l = conf_data->vrrp;
   element e;
   TIMEVAL vrrp_timer;
@@ -132,33 +144,12 @@ static int vrrp_timer_vrid_timeout(const int fd)
 
   for (e = LIST_HEAD(l); e; ELEMENT_NEXT(e)) {
     vrrp = ELEMENT_DATA(e);
-    if (timer_cmp(vrrp->vsrv->sands, vrrp_timer) == 0)
-      vrid = vrrp->vsrv->vrid;
+    if (timer_cmp(vrrp->sands, vrrp_timer) == 0)
+      vrid = vrrp->vrid;
   }
   return vrid;
 }
 
-/* Simple dump function
-static void vrrp_timer_dump(vrrp_instance *vrrp)
-{
-  vrrp_instance *ptr = vrrp;
-  TIMEVAL timer_now;
-  TIMEVAL timer;
-  long vrrp_timer = 0;
-
-  memset(&timer, 0, sizeof(struct timeval));
-
-  while (vrrp) {
-    timer = timer_sub_now(vrrp->vsrv->sands);
-    vrrp_timer = timer.tv_sec * TIMER_HZ + timer.tv_usec;
-    syslog(LOG_DEBUG, "Timer(vrid,value) : (%d,%d)", vrrp->vsrv->vrid, vrrp_timer);
-
-    vrrp = (vrrp_instance *)vrrp->next;
-  }
-  vrrp = ptr;
-}
-*/
-
 /* Thread functions */
 static void vrrp_register_workers(list l)
 {
@@ -228,7 +219,7 @@ void alloc_sock(list l, int ifindex, int proto)
 
 static void vrrp_create_sockpool(list l)
 {
-  vrrp_instance *vrrp;
+  vrrp_rt *vrrp;
   list p = conf_data->vrrp;
   element e;
   int ifindex;
@@ -236,8 +227,8 @@ static void vrrp_create_sockpool(list l)
 
   for (e = LIST_HEAD(p); e; ELEMENT_NEXT(e)) {
     vrrp = ELEMENT_DATA(e);
-    ifindex = ifname_to_idx(vrrp->vsrv->vif->ifname);
-    if (vrrp->vsrv->vif->auth_type == VRRP_AUTH_AH)
+    ifindex = IF_INDEX(vrrp->ifp);
+    if (vrrp->auth_type == VRRP_AUTH_AH)
       proto = IPPROTO_IPSEC_AH;
     else
       proto = IPPROTO_VRRP;
@@ -248,7 +239,7 @@ static void vrrp_create_sockpool(list l)
   }
 }
 
-static void vrrp_open_sockpool(list l)
+static int vrrp_open_sockpool(list l)
 {
   sock *sock;
   element e;
@@ -256,13 +247,16 @@ static void vrrp_open_sockpool(list l)
   for (e = LIST_HEAD(l); e; ELEMENT_NEXT(e)) {
     sock = ELEMENT_DATA(e);
     sock->fd = open_vrrp_socket(sock->proto, sock->ifindex);
+    if (sock->fd == -1)
+      return -1;
   }
+  return 1;
 }
 
 static void vrrp_set_fds(list l)
 {
   sock *sock;
-  vrrp_instance *vrrp;
+  vrrp_rt *vrrp;
   list p = conf_data->vrrp;
   element e_sock;
   element e_vrrp;
@@ -272,14 +266,14 @@ static void vrrp_set_fds(list l)
     sock = ELEMENT_DATA(e_sock);
     for (e_vrrp = LIST_HEAD(p); e_vrrp; ELEMENT_NEXT(e_vrrp)) {
       vrrp = ELEMENT_DATA(e_vrrp);
-      if (vrrp->vsrv->vif->auth_type == VRRP_AUTH_AH)
+      if (vrrp->auth_type == VRRP_AUTH_AH)
         proto = IPPROTO_IPSEC_AH;
       else
         proto = IPPROTO_VRRP;
 
-      if ((sock->ifindex == ifname_to_idx(vrrp->vsrv->vif->ifname)) &&
+      if ((sock->ifindex == IF_INDEX(vrrp->ifp)) &&
           (sock->proto == proto))
-        vrrp->vsrv->fd = sock->fd;
+        vrrp->fd = sock->fd;
     }
   }
 }
@@ -301,6 +295,7 @@ static void vrrp_set_fds(list l)
 int vrrp_dispatcher_init(thread *thread)
 {
   list pool;
+  int ret = 0;
 
   /* allocate the sockpool */
   pool = alloc_list(free_sock, dump_sock);
@@ -309,7 +304,13 @@ int vrrp_dispatcher_init(thread *thread)
   vrrp_create_sockpool(pool);
 
   /* open the VRRP socket pool */
-  vrrp_open_sockpool(pool);
+  ret = vrrp_open_sockpool(pool);
+  if (ret < 0) {
+    syslog(LOG_INFO, "Something is wrong with your hardware configuration");
+    free_list(pool);
+    thread_add_terminate_event(thread->master);
+    return -1;
+  }
 
   /* set VRRP instance fds to sockpool */
   vrrp_set_fds(pool);
@@ -321,12 +322,12 @@ int vrrp_dispatcher_init(thread *thread)
   dump_list(pool);
   free_list(pool);
 
-  return 0;
+  return 1;
 }
 
-static vrrp_instance *vrrp_search_instance_isync(char *isync)
+static vrrp_rt *vrrp_search_instance_isync(char *isync)
 {
-  vrrp_instance *vrrp;
+  vrrp_rt *vrrp;
   list l = conf_data->vrrp;
   element e;
 
@@ -338,32 +339,42 @@ static vrrp_instance *vrrp_search_instance_isync(char *isync)
   return NULL;
 }
 
-static vrrp_instance *vrrp_search_instance(const int vrid)
+static vrrp_rt *vrrp_search_instance(const int vrid)
 {
-  vrrp_instance *vrrp;
+  vrrp_rt *vrrp;
   list l = conf_data->vrrp;
   element e;
 
   for (e = LIST_HEAD(l); e; ELEMENT_NEXT(e)) {
     vrrp = ELEMENT_DATA(e);
-    if (vrrp->vsrv->vrid == vrid)
+    if (vrrp->vrid == vrid)
       return vrrp;
   }
   return NULL;
 }
 
-static void vrrp_handle_backup(vrrp_instance *instance
+static void vrrp_handle_backup(vrrp_rt *vrrp
                                , char *vrrp_buffer
                                , int len)
 {
-  vrrp_state_backup(instance, vrrp_buffer, len);
+  struct iphdr *iph = (struct iphdr *)vrrp_buffer;
+  ipsec_ah *ah;
+
+  if (iph->protocol == IPPROTO_IPSEC_AH) {
+    ah = (ipsec_ah *)(vrrp_buffer + sizeof(struct iphdr));
+    if (ah->seq_number >= vrrp->ipsecah_counter->seq_number) {
+      vrrp->ipsecah_counter->seq_number = ah->seq_number + 10;
+      vrrp->ipsecah_counter->cycle = 0;
+    }
+  }
+
+  vrrp_state_backup(vrrp, vrrp_buffer, len);
 }
 
-static void vrrp_handle_become_master(vrrp_instance *instance
+static void vrrp_handle_become_master(vrrp_rt *vrrp
                                      , char *vrrp_buffer
                                      , int len)
 {
-  vrrp_rt *vsrv = instance->vsrv;
   struct iphdr *iph = (struct iphdr *)vrrp_buffer;
   ipsec_ah *ah;
 
@@ -372,221 +383,421 @@ static void vrrp_handle_become_master(vrrp_instance *instance
    * with the remote IPSEC AH VRRP instance counter.
    */
   if (iph->protocol == IPPROTO_IPSEC_AH) {
+    syslog(LOG_INFO, "VRRP_Instance(%s) AH seq_num sync"
+                   , vrrp->iname);
     ah = (ipsec_ah *)(vrrp_buffer + sizeof(struct iphdr));
-    vsrv->ipsecah_counter->seq_number = ah->seq_number + 1;
-    vsrv->ipsecah_counter->cycle = 0;
+    vrrp->ipsecah_counter->seq_number = ah->seq_number + 5;
+    vrrp->ipsecah_counter->cycle = 0;
   }
+
+  /* Then jump to master state */
+  vrrp->wantstate = VRRP_STATE_MAST;
+  vrrp_state_goto_master(vrrp);
 }
 
-static void vrrp_handle_leave_master(vrrp_instance *instance
+static void vrrp_handle_leave_master(vrrp_rt *vrrp
                                      , char *vrrp_buffer
                                      , int len)
 {
-  if (vrrp_state_master_rx(instance, vrrp_buffer, len)) {
-    syslog(LOG_INFO, "VRRP_Instance(%s) Received higher prio advert"
-                   , instance->iname);
-    vrrp_state_leave_master(instance);
+  if (!IF_ISUP(vrrp->ifp)) {
+    syslog(LOG_INFO, "Kernel is reporting: interface %s DOWN"
+                   , IF_NAME(vrrp->ifp));
+    vrrp->wantstate = VRRP_STATE_GOTO_FAULT;
+  } else if (vrrp_state_master_rx(vrrp, vrrp_buffer, len))
+    vrrp->wantstate = VRRP_STATE_BACK;
+
+  vrrp_state_leave_master(vrrp);
+}
+
+static void vrrp_handle_leave_fault(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))) {
+        syslog(LOG_INFO, "VRRP_Instance(%s) prio is higher than received advert"
+                       , vrrp->iname);
+        vrrp_handle_become_master(vrrp, vrrp_buffer, len);
+      }
+    } else {
+      syslog(LOG_INFO, "VRRP_Instance(%s) prio is higher than received advert"
+                     , vrrp->iname);
+      vrrp_handle_become_master(vrrp, vrrp_buffer, len);
+    }
+  } else {
+    vrrp->state = VRRP_STATE_BACK;
+  }
+}
+
+static void vrrp_handle_leave_dummy_master(vrrp_rt *vrrp
+                                           , char *vrrp_buffer
+                                           , int len)
+{
+  vrrp_rt *vrrp_isync;
+
+  if (vrrp->isync) {
+    vrrp_isync = vrrp_search_instance_isync(vrrp->isync);
+
+    if (vrrp_isync->state == VRRP_STATE_FAULT &&
+        vrrp->wantstate   == VRRP_STATE_GOTO_DUMMY_MAST) {
+      vrrp->wantstate = VRRP_STATE_DUMMY_MAST;
+      syslog(LOG_INFO, "VRRP_Instance(%s) leaving DUMMY MASTER state"
+                      , vrrp->iname);
+      vrrp_state_leave_master(vrrp);
+    }
+
+    if (vrrp_isync->state != VRRP_STATE_FAULT) {
+      switch (vrrp_isync->state) {
+        case VRRP_STATE_BACK:
+          vrrp->state = VRRP_STATE_BACK;
+          break;
+        case VRRP_STATE_MAST:
+          vrrp_handle_become_master(vrrp, vrrp_buffer, len);
+          break;
+      }
+    }
   }
 }
 
-static int vrrp_handle_state(vrrp_instance *instance
+static int vrrp_handle_state(vrrp_rt *vrrp
                              , char *vrrp_buffer
                              , int len)
 {
   int previous_state;
 
-  previous_state = instance->vsrv->state;
+  previous_state = vrrp->state;
 
-  switch (instance->vsrv->state) {
+  switch (vrrp->state) {
     case VRRP_STATE_BACK:
-      vrrp_handle_backup(instance, vrrp_buffer, len);
+      vrrp_handle_backup(vrrp, vrrp_buffer, len);
       break;
     case VRRP_STATE_GOTO_MASTER:
-      vrrp_handle_become_master(instance, vrrp_buffer, len);
+      vrrp_handle_become_master(vrrp, vrrp_buffer, len);
+      break;
+    case VRRP_STATE_DUMMY_MAST:
+//      vrrp_handle_leave_dummy_master(vrrp, vrrp_buffer, len);
       break;
     case VRRP_STATE_MAST:
-      vrrp_handle_leave_master(instance, vrrp_buffer, len);
+      vrrp_handle_leave_master(vrrp, vrrp_buffer, len);
+      break;
+    case VRRP_STATE_FAULT:
+      vrrp_handle_leave_fault(vrrp, vrrp_buffer, len);
       break;
   }
 
   return previous_state;
 }
 
-static void vrrp_handle_goto_master(vrrp_instance *instance)
+static void vrrp_handle_goto_master(vrrp_rt *vrrp)
 {
-  vrrp_rt *vsrv = instance->vsrv;
+//  if (!IF_ISUP(vrrp->ifp)) {
+//    syslog(LOG_INFO, "Kernel is reporting: interface %s DOWN"
+//                   , IF_NAME(vrrp->ifp));
+//    vrrp->state = VRRP_STATE_FAULT;
+//  } else {
+    /* If becoming MASTER in IPSEC AH AUTH, we reset the anti-replay */
+    if (vrrp->ipsecah_counter->cycle) {
+      vrrp->ipsecah_counter->cycle      = 0;
+      vrrp->ipsecah_counter->seq_number = 0;
+    }
+
+    if (vrrp->wantstate != VRRP_STATE_GOTO_DUMMY_MAST)
+      vrrp->wantstate = VRRP_STATE_MAST;
 
-  /* If becoming MASTER in IPSEC AH AUTH, we reset the anti-replay */
-  if (vsrv->ipsecah_counter->cycle) {
-    vsrv->ipsecah_counter->cycle = 0;
-    vsrv->ipsecah_counter->seq_number = 0;
+    /* handle master state transition */
+    vrrp_state_goto_master(vrrp);
+//  }
+}
+
+static void vrrp_handle_master(vrrp_rt *vrrp)
+{
+  /* Check if interface we are running on is UP */
+  if (vrrp->wantstate != VRRP_STATE_GOTO_FAULT) {
+    if (!IF_ISUP(vrrp->ifp)) {
+      syslog(LOG_INFO, "Kernel is reporting: interface %s DOWN"
+                     , IF_NAME(vrrp->ifp));
+      vrrp->wantstate = VRRP_STATE_GOTO_FAULT;
+    }
   }
 
-  vsrv->state = VRRP_STATE_BACK;
-  vsrv->wantstate = VRRP_STATE_MAST;
+  /* Then perform the state transition */
+  if (vrrp->wantstate == VRRP_STATE_GOTO_FAULT ||
+      vrrp->wantstate == VRRP_STATE_BACK       ||
+      vrrp->ipsecah_counter->cycle) {
+    vrrp->ms_down_timer = 3 * vrrp->adver_int + VRRP_TIMER_SKEW(vrrp);
 
-  /* handle master state transition */
-  vrrp_state_goto_master(instance);
+    /* handle backup state transition */
+    vrrp_state_leave_master(vrrp);
+
+    if (vrrp->state == VRRP_STATE_BACK)
+      syslog(LOG_INFO, "VRRP_Instance(%s) Now in BACKUP state"
+                     , vrrp->iname);
+    if (vrrp->state == VRRP_STATE_FAULT)
+      syslog(LOG_INFO, "VRRP_Instance(%s) Now in FAULT state"
+                     , vrrp->iname);
+  } else if (vrrp->state == VRRP_STATE_MAST) {
+    /* send the VRRP advert */
+    vrrp_state_master_tx(vrrp, 0);
+  }
 }
 
-static void vrrp_handle_master(vrrp_instance *instance)
+static void vrrp_handle_fault(vrrp_rt *vrrp)
 {
-  vrrp_rt *vsrv = instance->vsrv;
+  if (IF_ISUP(vrrp->ifp)) {
+    syslog(LOG_INFO, "Kernel is reporting: interface %s UP"
+                   , IF_NAME(vrrp->ifp));
+    /* refresh the multicast fd */
+    new_vrrp_socket(vrrp);
 
-  if (vsrv->wantstate == VRRP_STATE_BACK ||
-      vsrv->ipsecah_counter->cycle) {
-    vsrv->ms_down_timer = 3 * vsrv->adver_int + VRRP_TIMER_SKEW(vsrv);
+    /*
+     * We force the IPSEC AH seq_number sync
+     * to be done in read advert handler.
+     * So we ignore this timeouted state until remote
+     * VRRP MASTER send its advert for the concerned
+     * instance.
+     */
+    if (vrrp->auth_type == VRRP_AUTH_AH) {
+      /*
+       * Transition to BACKUP state for AH
+       * seq number synchronization.
+       */
+      syslog(LOG_INFO, "VRRP_Instance(%s) in FAULT state jump to AH sync"
+                     , vrrp->iname);
+      vrrp->wantstate = VRRP_STATE_BACK;
+      vrrp_state_leave_master(vrrp);
+    } else {
+      /* Otherwise, we transit to init state */
+      if (vrrp->init_state == VRRP_STATE_BACK)
+        vrrp->state = VRRP_STATE_BACK;
+      else
+        vrrp_handle_goto_master(vrrp);
+    }
+  }
+}
 
-    /* handle backup state transition */
-    vsrv->state = VRRP_STATE_BACK;
-    vrrp_state_leave_master(instance);
+static void vrrp_handle_dummy_master(vrrp_rt *vrrp)
+{
+  /* Check if interface we are running on is UP */
+  if (!IF_ISUP(vrrp->ifp))
+    vrrp->wantstate = VRRP_STATE_GOTO_FAULT;
+
+  if (vrrp->wantstate == VRRP_STATE_GOTO_FAULT) {
+    vrrp->ms_down_timer = 3 * vrrp->adver_int + VRRP_TIMER_SKEW(vrrp);
 
-    syslog(LOG_INFO, "VRRP_Instance(%s) Becoming BACKUP"
-                   , instance->iname);
+    /* handle backup state transition */
+    vrrp_state_leave_master(vrrp);
   } else {
     /* send the VRRP advert */
-    vrrp_state_master_tx(instance, 0);
+    vrrp_state_master_tx(vrrp, 0);
   }
 }
 
-static int vrrp_handle_state_timeout(vrrp_instance *instance)
+static int vrrp_handle_state_timeout(vrrp_rt *vrrp)
 {
   int previous_state;
 
-  previous_state = instance->vsrv->state;
+  previous_state = vrrp->state;
 
-  switch (instance->vsrv->state) {
+  switch (vrrp->state) {
     case VRRP_STATE_BACK:
-      vrrp_handle_goto_master(instance);
+      vrrp_handle_goto_master(vrrp);
       break;
     case VRRP_STATE_GOTO_MASTER:
-      vrrp_handle_goto_master(instance);
+      vrrp_handle_goto_master(vrrp);
+      break;
+    case VRRP_STATE_DUMMY_MAST:
+      vrrp_handle_dummy_master(vrrp);
       break;
     case VRRP_STATE_MAST:
-      vrrp_handle_master(instance);
+      vrrp_handle_master(vrrp);
       break;
     case VRRP_STATE_FAULT:
-      vrrp_handle_master(instance);
+      vrrp_handle_fault(vrrp);
       break;
   }
 
   return previous_state;
 }
 
-/* Our read packet dispatcher */
-int vrrp_read_dispatcher_thread(thread *thread)
+/* Handle dispatcher read timeout */
+static int vrrp_dispatcher_read_to(int fd)
 {
-  vrrp_instance *vrrp_isync;
-  vrrp_instance *vrrp_instance;
-  long vrrp_timer = 0;
-  char *vrrp_buffer;
-  struct iphdr *iph;
-  vrrp_pkt *hd;
-  int len = 0;
+  vrrp_rt *vrrp;
+  vrrp_rt *vrrp_isync;
   int vrid = 0;
   int previous_state = 0;
 
-  if (thread->type == THREAD_READ_TIMEOUT) {
-
-    /* Searching for matching instance */
-    vrid = vrrp_timer_vrid_timeout(thread->u.fd);
-    vrrp_instance = vrrp_search_instance(vrid);
-
-    previous_state = vrrp_handle_state_timeout(vrrp_instance);
-
-    /* handle master instance synchronization */
-    if (previous_state == VRRP_STATE_BACK && vrrp_instance->isync) {
-      vrrp_isync = vrrp_search_instance_isync(vrrp_instance->isync);
-
-      if (vrrp_isync->vsrv->state == VRRP_STATE_BACK) {
-        syslog(LOG_INFO, "VRRP_Instance(%s) must be sync with %s"
-                        , vrrp_instance->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 tables */
-        syslog(LOG_INFO, "VRRP_Instance(%s) gratuitous arp on %s"
-                       , vrrp_isync->iname
-                       , vrrp_isync->vsrv->vif->ifname);
-        vrrp_isync->vsrv->state = VRRP_STATE_MAST;
-        vrrp_send_gratuitous_arp(vrrp_isync);
-      }
-    }
+  /* Searching for matching instance */
+  vrid = vrrp_timer_vrid_timeout(fd);
+  vrrp = vrrp_search_instance(vrid);
 
-    /*
-     * We are sure the instance exist. So we can
-     * compute new sands timer safely.
-     */
-    vrrp_init_instance_sands(vrrp_instance);
+  previous_state = vrrp_handle_state_timeout(vrrp);
 
-  } else {
+  /* handle master instance synchronization */
+  if (previous_state == VRRP_STATE_BACK && 
+      vrrp->state    == VRRP_STATE_MAST &&
+      vrrp->isync) {
+    vrrp_isync = vrrp_search_instance_isync(vrrp->isync);
 
-    /* allocate & clean the read buffer */
-    vrrp_buffer = (char *)MALLOC(VRRP_PACKET_TEMP_LEN);
-
-    /* read & affect received buffer */
-    len = read(thread->u.fd, vrrp_buffer, VRRP_PACKET_TEMP_LEN);
-    iph = (struct iphdr *)vrrp_buffer;
-
-    /* GCC bug : Workaround */
-    hd = (vrrp_pkt *) ((char *)iph + (iph->ihl << 2));
-    if (iph->protocol == IPPROTO_IPSEC_AH)
-      hd = (vrrp_pkt *) ((char *)hd + vrrp_ipsecah_len());
-    /* GCC bug : end */
-
-    /* Searching for matching instance */
-    vrrp_instance = vrrp_search_instance(hd->vrid);
-
-    if (vrrp_instance) {
-
-      previous_state = vrrp_handle_state(vrrp_instance, vrrp_buffer, len);
-
-      /* handle backup instance synchronization */
-      if (previous_state == VRRP_STATE_MAST && 
-          vrrp_instance->vsrv->state == VRRP_STATE_BACK &&
-          vrrp_instance->isync) {
-        vrrp_isync = vrrp_search_instance_isync(vrrp_instance->isync);
-
-        /* synchronized instance probably failed */
-        if (vrrp_isync->vsrv->state == VRRP_STATE_MAST &&
-            vrrp_isync->vsrv->init_state == VRRP_STATE_MAST) {
-          syslog(LOG_INFO, "VRRP_Instance(%s) transition to FAULT state"
-                         , vrrp_instance->iname);
-          vrrp_isync->vsrv->state = VRRP_STATE_FAULT;
-        } else if (vrrp_isync->vsrv->state == VRRP_STATE_MAST) {
-          syslog(LOG_INFO, "VRRP_Instance(%s) must be sync with %s"
-                         , vrrp_instance->iname
-                         , vrrp_isync->iname);
-
-          /* Transition to BACKUP state */
-          vrrp_isync->vsrv->wantstate = VRRP_STATE_BACK;
-        }
-      }
+    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 (previous_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) {
       /*
-       * Refresh sands only if found matching instance.
-       * Otherwize the packet is simply ignored...
-       *
-       * FIXME: Add a dropping packet framework to not
-       *        degrade the instance timer during dropping.
+       * 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_init_instance_sands(vrrp_instance);
+      //vrrp_isync->wantstate = VRRP_STATE_BACK;
+      vrrp_isync->wantstate = VRRP_STATE_GOTO_FAULT;
     }
+  }
 
-    /* cleanup the room */
+  /*
+   * 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 (previous_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;
+  }
+
+  /*
+   * We are sure the instance exist. So we can
+   * compute new sands timer safely.
+   */
+  vrrp_init_instance_sands(vrrp);
+  return vrrp->fd;
+}
+
+/* Handle dispatcher read packet */
+static int vrrp_dispatcher_read(int fd)
+{
+  vrrp_rt *vrrp;
+  vrrp_rt *vrrp_isync;
+  char *vrrp_buffer;
+  struct iphdr *iph;
+  vrrp_pkt *hd;
+  int len = 0;
+  int previous_state = 0;
+
+  /* allocate & clean the read buffer */
+  vrrp_buffer = (char *)MALLOC(VRRP_PACKET_TEMP_LEN);
+
+  /* read & affect received buffer */
+  len = read(fd, vrrp_buffer, VRRP_PACKET_TEMP_LEN);
+  iph = (struct iphdr *)vrrp_buffer;
+
+  /* GCC bug : Workaround */
+  hd = (vrrp_pkt *) ((char *)iph + (iph->ihl << 2));
+  if (iph->protocol == IPPROTO_IPSEC_AH)
+    hd = (vrrp_pkt *) ((char *)hd + vrrp_ipsecah_len());
+  /* GCC bug : end */
+
+  /* Searching for matching instance */
+  vrrp = vrrp_search_instance(hd->vrid);
+
+  /* If no instance found => ignore the advert */
+  if (!vrrp) {
     FREE(vrrp_buffer);
+    return fd;
+  }
+
+  previous_state = vrrp_handle_state(vrrp, vrrp_buffer, len);
 
+  /* handle backup instance synchronization */
+  if (previous_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;
+    }
   }
 
+  /*
+   * Refresh sands only if found matching instance.
+   * Otherwize the packet is simply ignored...
+   *
+   * FIXME: Add a dropping packet framework to not
+   *        degrade the instance timer during dropping.
+   */
+  vrrp_init_instance_sands(vrrp);
+
+  /* cleanup the room */
+  FREE(vrrp_buffer);
+
+  return fd;
+}
+
+/* Our read packet dispatcher */
+int vrrp_read_dispatcher_thread(thread *thread)
+{
+  long vrrp_timer = 0;
+  int fd;
+
+  /* Dispatcher state handler */
+  if (thread->type == THREAD_READ_TIMEOUT)
+    fd = vrrp_dispatcher_read_to(thread->u.fd);
+  else
+    fd = vrrp_dispatcher_read(thread->u.fd);
+
   /* register next dispatcher thread */
-  vrrp_timer = vrrp_timer_fd(thread->u.fd);
+  vrrp_timer = vrrp_timer_fd(fd);
   thread_add_read(thread->master, vrrp_read_dispatcher_thread
                                 , NULL
-                                , thread->u.fd
+                                , fd
                                 , vrrp_timer);
   return 0;
 }
@@ -594,6 +805,7 @@ int vrrp_read_dispatcher_thread(thread *thread)
 /* Register VRRP thread */
 void register_vrrp_thread(void)
 {
+  /* Init the packet dispatcher */
   if (!LIST_ISEMPTY(conf_data->vrrp))
     thread_add_event(master, vrrp_dispatcher_init
                            , NULL
index 7418a89..6d674ac 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Part:        vrrp_scheduler.c include file.
  * 
- * Version:     $Id: vrrp_scheduler.h,v 0.5.3 2002/02/24 23:50:11 acassen Exp $
+ * Version:     $Id: vrrp_scheduler.h,v 0.5.5 2002/04/10 02:34:23 acassen Exp $
  * 
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *              
 
 /* local include */
 #include "scheduler.h"
-#include "data.h"
+#include "vrrp.h"
 
 /*
  * Our instance dispatcher use a socket pool.
- * That way we handle VRRP protocole type per
+ * That way we handle VRRP protocol type per
  * physical interface.
  */
 typedef struct {
@@ -46,14 +46,6 @@ typedef struct {
 } sock;
 
 /* extern prototypes */
-extern int open_vrrp_socket(const int proto, const int index);
-extern int ifname_to_idx(const char *ifname);
-extern void vrrp_send_gratuitous_arp(vrrp_instance *vrrp_instance);
 extern int vrrp_read_dispatcher_thread(thread *thread);
-extern int vrrp_state_master_rx(vrrp_instance *instance, char *buf, int buflen);
-extern void vrrp_state_master_tx(vrrp_instance *instance, const int prio);
-extern void vrrp_state_backup(vrrp_instance *instance, char *buf, int buflen);
-extern void vrrp_state_goto_master(vrrp_instance *vrrp_instance);
-extern void vrrp_state_leave_master(vrrp_instance *instance);
 
 #endif