keepalived-0.6.1 v0.6.1
authorAlexandre Cassen <acassen@freebox.fr>
Thu, 13 Jun 2002 15:00:02 +0000 (17:00 +0200)
committerAlexandre Cassen <acassen@freebox.fr>
Mon, 28 Sep 2009 08:58:55 +0000 (10:58 +0200)
* keepalived-0.6.1 released.
* Aneesh Kumar, <aneesh.kumar@digital.com> and I added support to
  Cluster Infrastructure checkers. Providing HA-LVS for their cluster
  project (http://ci-linux.sourceforge.net/). The new checker added
  provide a derivation to the internal CI healthcheck mechanism.
* Enhanced the Kernel netlink reflector to drive global healthcheckers
  activity. The policy implemented here is : If healthchecker is performing
  test on a service that belong to a VIP not owned by the director, then
  the healthchecker is suspended. This suspend/active state is particulary
  usefull if runing VRRP for HA => That way the backup LVS will not charge
  the realserver pool since LVS VIP is owned by master LVS.
* Cosmetics patches into the vector lib.
* VRRP : Rewrote the previous VRRP synchronization instance policy.
  Created a new config block called "vrrp_sync_group" that define VRRP
  instances synchronization dependences. That way we replace the previous
  "by-pair" sync approach by this "by-group" approach. This can be useefull
  for firewall HA with many NICs. Created a dedicated framework to speed up
  takeover synchronization.
* VRRP : Added support to CIDR notation for VRRP VIPs definitions
  => VRRP VIPs definition like a.b.c.d/e. By default "e" value is set to 32.
* VRRP : Added support to multicast source IP address selection
  => "mcast_src_ip" keyword. Can be usefull for strongly filtered env.
  The mcast group subscription is done using the NIC default IP after this
  mcast_src_ip is used if specified.
* VRRP : Enhanced the link media failure detection. Added support to the
  new kernel SIOCETHTOOL probing for ETHTOOL_GLINK command. New drivers
  use this ETHTOOL interface to report link failure activity. During
  bootstrap a probe is done to determine the proper polling method to
  use for link media failure detection. The policy used is : probe for
  SIOCGMIIREG if not supported then try SIOCETHTOOL GLINK probe, otherwise
  use a ioctl SIOCGIFFLAGS polling function mirroring kernel NIC flags to
  localy reflected representation.
* Ramon Kagan, <rkagan@YorkU.CA> and I updated the UserGuide.pdf.

65 files changed:
ChangeLog
Makefile.in
VERSION
check_api.c
check_api.h
check_ci.c [new file with mode: 0644]
check_ci.h [new file with mode: 0644]
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/rc.d/init.d/keepalived.init
ipfwwrapper.c
ipfwwrapper.h
ipvswrapper.c
ipvswrapper.h
ipwrapper.c
ipwrapper.h
layer4.c
layer4.h
list.c
list.h
main.c
main.h
memory.c
memory.h
parser.c
parser.h
pidfile.c
pidfile.h
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
vrrp_if.h
vrrp_ipaddress.c
vrrp_ipaddress.h
vrrp_ipsecah.c
vrrp_ipsecah.h
vrrp_netlink.c
vrrp_netlink.h
vrrp_scheduler.c
vrrp_scheduler.h
vrrp_sync.c [new file with mode: 0644]
vrrp_sync.h [new file with mode: 0644]

index 8235469..f164758 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,38 @@
+2002-06-13  Alexandre Cassen  <acassen@linux-vs.org>
+       * keepalived-0.6.1 released.
+       * Aneesh Kumar, <aneesh.kumar@digital.com> and I added support to
+         Cluster Infrastructure checkers. Providing HA-LVS for their cluster
+         project (http://ci-linux.sourceforge.net/). The new checker added
+         provide a derivation to the internal CI healthcheck mechanism.
+       * Enhanced the Kernel netlink reflector to drive global healthcheckers
+         activity. The policy implemented here is : If healthchecker is performing
+         test on a service that belong to a VIP not owned by the director, then
+         the healthchecker is suspended. This suspend/active state is particulary
+         usefull if runing VRRP for HA => That way the backup LVS will not charge
+         the realserver pool since LVS VIP is owned by master LVS.
+       * Cosmetics patches into the vector lib.
+       * VRRP : Rewrote the previous VRRP synchronization instance policy.
+         Created a new config block called "vrrp_sync_group" that define VRRP
+         instances synchronization dependences. That way we replace the previous
+         "by-pair" sync approach by this "by-group" approach. This can be useefull
+         for firewall HA with many NICs. Created a dedicated framework to speed up
+         takeover synchronization.
+       * VRRP : Added support to CIDR notation for VRRP VIPs definitions
+         => VRRP VIPs definition like a.b.c.d/e. By default "e" value is set to 32.
+       * VRRP : Added support to multicast source IP address selection
+         => "mcast_src_ip" keyword. Can be usefull for strongly filtered env.
+         The mcast group subscription is done using the NIC default IP after this
+         mcast_src_ip is used if specified.
+       * VRRP : Enhanced the link media failure detection. Added support to the
+         new kernel SIOCETHTOOL probing for ETHTOOL_GLINK command. New drivers
+         use this ETHTOOL interface to report link failure activity. During
+         bootstrap a probe is done to determine the proper polling method to
+         use for link media failure detection. The policy used is : probe for
+         SIOCGMIIREG if not supported then try SIOCETHTOOL GLINK probe, otherwise
+         use a ioctl SIOCGIFFLAGS polling function mirroring kernel NIC flags to
+         localy reflected representation.
+       * Ramon Kagan, <rkagan@YorkU.CA> and I updated the UserGuide.pdf.
+
 2002-05-30  Alexandre Cassen  <acassen@linux-vs.org>
        * keepalived-0.5.9 released.
        * Added support to realserver_group. The work is not yet finished since
index abbf812..f2c03d8 100644 (file)
@@ -8,6 +8,7 @@ EXEC = keepalived
 KERNEL    := _KRNL_2_$(shell uname -r | cut -d'.' -f2)_
 IPVS_FLAG := @IPVS_SUPPORT@
 VRRP_FLAG := @VRRP_SUPPORT@
+CI_LINUX  := @CI_LINUX@
 
 prefix      = @prefix@
 exec_prefix = @exec_prefix@
@@ -56,17 +57,23 @@ ifeq ($(VRRP_FLAG),_WITH_VRRP_)
 VRRP_OBJS = \
        vrrp.o \
        vrrp_scheduler.o \
+       vrrp_sync.o \
        vrrp_netlink.o \
        vrrp_if.o \
        vrrp_ipaddress.o \
        vrrp_ipsecah.o
 endif
 
+ifeq ($(CI_LINUX),_WITH_CI_LINUX_)
+CI_LINUX_OBJ = check_ci.o
+CIFLAGS = -D$(CI_LINUX)
+endif
+
 INCLUDE = -I/usr/src/linux/include
-OBJS    = $(CORE_OBJS) $(IPVS_OBJS) $(VRRP_OBJS)
+OBJS    = $(CORE_OBJS) $(IPVS_OBJS) $(VRRP_OBJS) $(CI_LINUX_OBJ)
 
 .c.o:
-       $(CC) -o $@ $(CFLAGS) $(IPVSFLAGS) $(INCLUDE) -c $*.c
+       $(CC) -o $@ $(CFLAGS) $(IPVSFLAGS) $(CIFLAGS) $(INCLUDE) -c $*.c
 
 all:    $(EXEC)
        strip $(EXEC)
diff --git a/VERSION b/VERSION
index 416bfb0..ee6cdce 100644 (file)
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-0.5.9
+0.6.1
index 904366e..d89953c 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Part:        Checkers registration.
  *
- * Version:     $Id: check_api.c,v 0.5.9 2002/05/30 16:05:31 acassen Exp $
+ * Version:     $Id: check_api.c,v 0.6.1 2002/06/13 15:12:26 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
@@ -28,6 +28,9 @@
 #include "check_tcp.h"
 #include "check_http.h"
 #include "check_ssl.h"
+#ifdef _WITH_CI_LINUX_
+  #include "check_ci.h"
+#endif
 
 extern thread_master *master;
 extern data *conf_data;
@@ -64,12 +67,12 @@ void queue_checker(void (*free) (void *), void (*dump) (void *)
   real_server *rs    = LIST_TAIL_DATA(vs->rs);
   checker *chk       = (checker *)MALLOC(sizeof(checker));
 
-  chk->free   = free;
-  chk->dump   = dump;
-  chk->launch = launch;
-  chk->vs     = vs;
-  chk->rs     = rs;
-  chk->data   = data;
+  chk->free    = free;
+  chk->dump    = dump;
+  chk->launch  = launch;
+  chk->vs      = vs;
+  chk->rs      = rs;
+  chk->data    = data;
 
   /* queue the checker */
   list_add(checkers_queue, chk);
@@ -104,6 +107,34 @@ void register_checkers_thread(void)
   }
 }
 
+/* Sync checkers activity with netlink kernel reflection */
+void update_checker_activity(uint32_t address, int enable)
+{
+  checker *checker;
+  element e;
+
+  /* Processing Healthcheckers queue */
+  if (!LIST_ISEMPTY(checkers_queue))
+    for (e = LIST_HEAD(checkers_queue); e; ELEMENT_NEXT(e)) {
+      checker = ELEMENT_DATA(e);
+      if (CHECKER_VIP(checker) == address) {
+        if (!CHECKER_ENABLED(checker) && enable) {
+          syslog(LOG_INFO, "Netlink reflector reports IP %s added"
+                         , ip_ntoa(address));
+          syslog(LOG_INFO, "Activating healtchecker for VIP %s"
+                         , ip_ntoa(address));
+        }
+        if (CHECKER_ENABLED(checker) && !enable) {
+          syslog(LOG_INFO, "Netlink reflector reports IP %s removed"
+                         , ip_ntoa(address));
+          syslog(LOG_INFO, "Suspending healtchecker for VIP %s"
+                         , ip_ntoa(address));
+        }
+        checker->enabled = enable;
+      }
+    }
+}
+
 /* Install checkers keywords */
 void install_checkers_keyword(void)
 {
@@ -111,4 +142,7 @@ void install_checkers_keyword(void)
   install_tcp_check_keyword();
   install_http_check_keyword();
   install_ssl_check_keyword();
+#ifdef _WITH_CI_LINUX_
+  install_ci_check_keyword();
+#endif
 }
index 2e1436b..c9c779a 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Part:        Checkers arguments structures definitions.
  *
- * Version:     $Id: check_api.h,v 0.5.9 2002/05/30 16:05:31 acassen Exp $
+ * Version:     $Id: check_api.h,v 0.6.1 2002/06/13 15:12:26 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
@@ -32,9 +32,10 @@ typedef struct _checker {
   void (*free) (void *);
   void (*dump) (void *);
   int (*launch)        (struct _thread *);
-  virtual_server       *vs;    /* pointer to the checker thread virtualserver */
-  real_server          *rs;    /* pointer to the checker thread realserver */
+  virtual_server       *vs;     /* pointer to the checker thread virtualserver */
+  real_server          *rs;     /* pointer to the checker thread realserver */
   void                 *data;
+  int                  enabled; /* Activation flag */
 } checker;
 
 /* Checkers queue */
@@ -46,9 +47,14 @@ list checkers_queue;
 #define CHECKER_GET() (CHECKER_DATA(LIST_TAIL_DATA(checkers_queue)))
 #define CHECKER_VALUE_INT(X) (atoi(VECTOR_SLOT(X,1)))
 #define CHECKER_VALUE_STRING(X) (set_value(X))
+#define CHECKER_VIP(C)   (SVR_IP((C)->vs))
+#define CHECKER_VPORT(C) (SVR_PORT((C)->vs))
 #define CHECKER_RIP(C)   (SVR_IP((C)->rs))
 #define CHECKER_RPORT(C) (SVR_PORT((C)->rs))
 #define CHECKER_VHOST(C) (VHOST((C)->vs))
+#define CHECKER_ENABLED(C) ((C)->enabled)
+#define CHECKER_ENABLE(C)  ((C)->enabled = 1)
+#define CHECKER_DISABLE(C) ((C)->enabled = 0)
 
 /* Prototypes definition */
 extern void init_checkers_queue(void);
@@ -59,5 +65,6 @@ extern void dump_checkers_queue(void);
 extern void free_checkers_queue(void);
 extern void register_checkers_thread(void);
 extern void install_checkers_keyword(void);
+extern void update_checker_activity(uint32_t address, int enable);
 
 #endif
diff --git a/check_ci.c b/check_ci.c
new file mode 100644 (file)
index 0000000..9b7c2e2
--- /dev/null
@@ -0,0 +1,189 @@
+/*
+ * Soft:        Keepalived is a failover program for the LVS project
+ *              <www.linuxvirtualserver.org>. It monitor & manipulate
+ *              a loadbalanced server pool using multi-layer checks.
+ *
+ * Part:        CI-LINUX checker. Integration to Compaq Cluster Infrastructure.
+ *
+ * Version:     $Id: check_ci.c,v 0.6.1 2002/06/13 15:12:26 acassen Exp $
+ *
+ * Authors:     Alexandre Cassen, <acassen@linux-vs.org>
+ *              Aneesh Kumar K.V, <aneesh.kumar@digital.com>
+ *
+ *              This program is distributed in the hope that it will be useful,
+ *              but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *              MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *              See the GNU General Public License for more details.
+ *
+ *              This program is free software; you can redistribute it and/or
+ *              modify it under the terms of the GNU General Public License
+ *              as published by the Free Software Foundation; either version
+ *              2 of the License, or (at your option) any later version.
+ */
+
+#include "check_ci.h"
+#include "check_api.h"
+#include "memory.h"
+#include "parser.h"
+#include "smtp.h"
+#include "ipwrapper.h"
+
+/* CI nodemap declaration */
+static nodenum_ip_map_t *nodemap;
+
+/* Configuration stream handling */
+void free_ci_check(void *data)
+{
+  if (nodemap) {
+    FREE(nodemap);
+    nodemap = NULL;
+  }
+}
+void dump_ci_check(void *data)
+{
+  syslog(LOG_INFO, "   Keepalive method = CI-LINUX");
+}
+void ci_get_handler(vector strvec)
+{
+  int size = sizeof(nodenum_ip_map_t)*cluster_maxnodes()+1;
+  nodemap = (nodenum_ip_map_t *)ALLOC(size);
+
+  /*
+   * If we can not initialize node map we don t queue a new checker.
+   * The default action if so is:
+   *   The realserver activity will not be monitored by the CI-LINUX
+   *   Healchecker. This mean that this realserver will be present into
+   *   LVS topology even if it is failing.
+   */
+  if (initialize_nodemap(nodemap) < 0) {
+    syslog(LOG_ERR, "[CI-LINUX] Failed to initialize the node map from %s"
+                  , CLUSTERTAB);
+  } else
+    queue_checker(free_ci_check, dump_ci_check
+                               , ci_check_thread
+                               , NULL);
+}
+void install_ci_check_keyword(void)
+{
+  install_keyword("CI-LINUX",  &ci_get_handler);
+}
+
+int initialize_nodemap(nodenum_ip_map_t *nodemap)
+{
+  FILE *fp;
+  char buf[BUFFSIZE];
+  int node_number ;
+
+  if ((fp = fopen(CLUSTERTAB,"r")) == NULL)
+    return -1;
+
+  while (fscanf(fp,"%s",buf) != EOF) {
+    if (buf[0] == '#') {
+      if (fscanf(fp, "%[^\n]", buf) == EOF) {
+        syslog(LOG_ERR, "[CI-LINUX] %s File Format Error", CLUSTERTAB);
+        return -1;
+      }
+      bzero(buf,BUFFSIZE);
+      continue;
+    }
+    node_number = atoi(buf);
+    if (node_number > cluster_maxnodes()) {
+      syslog(LOG_ERR, "[CI-LINUX] Node number greater than MAX node num\n");
+      return -1;
+    }
+    if (fscanf(fp, "%s",buf) == EOF) {
+      syslog(LOG_ERR, "[CI-LINUX] %s File Format Error", CLUSTERTAB);
+      return -1;
+    }
+    nodemap[node_number].addr_ip = inet_addr(buf);
+    if (fscanf(fp, "%[^\n]", buf) == EOF) {
+      syslog(LOG_ERR, "[CI-LINUX] %s File Format Error", CLUSTERTAB);
+      return -1;
+    }
+    bzero(buf, BUFFSIZE);
+  }
+  return 1;
+}
+
+clusternode_t address_to_nodenum(uint32_t addr_ip)
+{
+  int i ;
+  int max_nodes = cluster_maxnodes();
+
+  for (i = 1; i<= max_nodes; i++) {
+    if (nodemap[i].addr_ip == addr_ip)
+    return i;
+  }
+  return 0; /* Not a valid node */
+}
+
+int nodestatus(uint32_t addr_ip)
+{
+  int node_num;
+  clusternode_info_t ni;
+
+  if ((node_num = address_to_nodenum(addr_ip)) == 0)
+    return UNKNOWN_NODE;
+
+  if (clusternode_info(node_num, sizeof(ni), &ni) >= 0)
+    /*
+     * I am insterested only in two state
+     * either fully up or down.
+     */
+    return (ni.node_state == CLUSTERNODE_UP)?UP:DOWN;
+  else
+    syslog(LOG_ERR, "[CI-LINUX] Error in getting the cluster information");
+
+  return UNKNOWN_NODE;
+}
+
+/* Cluster Infrastructure checker thread */
+int ci_check_thread(thread *thread)
+{
+  checker *checker = THREAD_ARG(thread);
+  int status ;
+
+  /*
+   * Register a new checker thread & return
+   * if checker is disabled
+   */
+  if (!CHECKER_ENABLED(checker)) {
+    thread_add_timer(thread->master, ci_check_thread
+                                   , checker
+                                   , checker->vs->delay_loop);
+    return 0;
+  }
+
+
+  /* Check the CI node status */
+  status = nodestatus(CHECKER_RIP(checker));
+
+  switch(status) {
+    case UP:
+      if (!ISALIVE(checker->rs)) {
+        smtp_alert(thread->master, checker->rs
+                                 , NULL
+                                 , "UP"
+                                 , "=> CI-Linux  CHECK succeed on service <=\n\n");
+        perform_svr_state(UP, checker->vs, checker->rs);
+      }
+      break;
+    case DOWN:
+      if (ISALIVE(checker->rs)) {
+        smtp_alert(thread->master, checker->rs
+                                 , NULL
+                                 , "DOWN"
+                                 , "=> CI-Linux CHECK failed on service <=\n\n");
+        perform_svr_state(DOWN, checker->vs, checker->rs);
+      }
+      break;
+    default:
+      syslog(LOG_ERR,"[CI-LINUX] Unknown node status");
+  }
+
+  /* Register the next check */
+  thread_add_timer(thread->master, ci_check_thread
+                                 , checker
+                                 , checker->vs->delay_loop);
+  return 0;
+}
diff --git a/check_ci.h b/check_ci.h
new file mode 100644 (file)
index 0000000..a65fb3a
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ * Soft:        Keepalived is a failover program for the LVS project
+ *              <www.linuxvirtualserver.org>. It monitor & manipulate
+ *              a loadbalanced server pool using multi-layer checks.
+ *
+ * Part:        check_ci.c include file.
+ *
+ * Version:     $Id: check_ci.h,v 0.6.1 2002/06/13 15:12:26 acassen Exp $
+ *
+ * Authors:     Alexandre Cassen, <acassen@linux-vs.org>
+ *              Aneesh Kumar K.V, <aneesh.kumar@digital.com>
+ *
+ *              This program is distributed in the hope that it will be useful,
+ *              but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *              MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *              See the GNU General Public License for more details.
+ *
+ *              This program is free software; you can redistribute it and/or
+ *              modify it under the terms of the GNU General Public License
+ *              as published by the Free Software Foundation; either version
+ *              2 of the License, or (at your option) any later version.
+ */
+
+#ifndef _CI_LINUX_H
+#define _CI_LINUX_H
+
+/* system includes */
+#include <signal.h>
+#include <pthread.h>
+#include <linux/cluster.h> /* Should change this to cluster.h alone */
+#include <syslog.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+/* local includes */
+#include "scheduler.h"
+
+#define SIGCLUSTER 2
+#define CLUSTERTAB "/etc/clustertab"
+#define BUFFSIZE 100
+#define UP 1
+#define DOWN 2
+#define UNKNOWN_NODE 0
+
+typedef struct nodenum_ip_map {
+  uint32_t      addr_ip;
+} nodenum_ip_map_t;
+
+/* Prototypes defs */
+extern int initialize_nodemap(nodenum_ip_map_t *nodemap);
+extern clusternode_t address_to_nodenum(uint32_t addr_ip);
+extern int nodestatus(uint32_t addr_ip);
+extern void install_ci_check_kerword(void);
+
+#endif
index 428368a..eb561b9 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Part:        WEB CHECK. Common HTTP/SSL checker primitives.
  *
- * Version:     $Id: check_http.c,v 0.5.9 2002/05/30 16:05:31 acassen Exp $
+ * Version:     $Id: check_http.c,v 0.6.1 2002/06/13 15:12:26 acassen Exp $
  *
  * Authors:     Alexandre Cassen, <acassen@linux-vs.org>
  *              Jan Holmberg, <jan@artech.net>
@@ -691,6 +691,17 @@ int http_connect_thread(thread *thread)
   enum connect_result status;
   int fd;
 
+  /*
+   * Register a new checker thread & return
+   * if checker is disabled
+   */
+  if (!CHECKER_ENABLED(checker)) {
+    thread_add_timer(thread->master, http_connect_thread
+                                   , checker
+                                   , checker->vs->delay_loop);
+    return 0;
+  }
+
   /* Find eventual url end */
   fetched_url = fetch_next_url(http_get_check);
 
index 2b85891..16565b4 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Part:        check_http.c include file.
  *
- * Version:     $Id: check_http.h,v 0.5.9 2002/05/30 16:05:31 acassen Exp $
+ * Version:     $Id: check_http.h,v 0.6.1 2002/06/13 15:12:26 acassen Exp $
  *
  * Authors:     Alexandre Cassen, <acassen@linux-vs.org>
  *              Jan Holmberg, <jan@artech.net>
index c9f6468..7f83605 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.9 2002/05/30 16:05:31 acassen Exp $
+ * Version:     $Id: check_misc.c,v 0.6.1 2002/06/13 15:12:26 acassen Exp $
  *
  * Authors:     Alexandre Cassen, <acassen@linux-vs.org>
  *              Eric Jarman, <ehj38230@cmsu2.cmsu.edu>
@@ -107,6 +107,12 @@ int misc_check_thread(thread *thread)
   thread_add_timer(thread->master, misc_check_thread
                                  , checker
                                  , checker->vs->delay_loop);
+  /*
+   * Register a new checker thread & return
+   * if checker is disabled
+   */
+  if (!CHECKER_ENABLED(checker))
+    return 0;
 
   /* Daemonization to not degrade our scheduling timer */
   if (xdaemon(0, 0, 1))
index a95d1e3..ebed5d3 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Part:        check_misc.c include file.
  *
- * Version:     $Id: check_misc.h,v 0.5.9 2002/05/30 16:05:31 acassen Exp $
+ * Version:     $Id: check_misc.h,v 0.6.1 2002/06/13 15:12:26 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *              Eric Jarman, <ehj38230@cmsu2.cmsu.edu>
index e7b1065..b3655d6 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.9 2002/05/30 16:05:31 acassen Exp $
+ * Version:     $Id: check_ssl.c,v 0.6.1 2002/06/13 15:12:26 acassen Exp $
  *
  * Authors:     Alexandre Cassen, <acassen@linux-vs.org>
  *              Jan Holmberg, <jan@artech.net>
index cf0cbcf..2c7776e 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Part:        check_http.c include file.
  *
- * Version:     $Id: check_http.h,v 0.5.9 2002/05/30 16:05:31 acassen Exp $
+ * Version:     $Id: check_http.h,v 0.6.1 2002/06/13 15:12:26 acassen Exp $
  *
  * Authors:     Alexandre Cassen, <acassen@linux-vs.org>
  *              Jan Holmberg, <jan@artech.net>
index 7b6cc57..8a028de 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Part:        TCP checker.
  *
- * Version:     $Id: check_tcp.c,v 0.5.9 2002/05/30 16:05:31 acassen Exp $
+ * Version:     $Id: check_tcp.c,v 0.6.1 2002/06/13 15:12:26 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
@@ -152,6 +152,17 @@ int tcp_connect_thread(thread *thread)
   checker   = THREAD_ARG(thread);
   tcp_check = CHECKER_ARG(checker);
 
+  /*
+   * Register a new checker thread & return
+   * if checker is disabled
+   */
+  if (!CHECKER_ENABLED(checker)) {
+    thread_add_timer(thread->master, tcp_connect_thread
+                                   , checker
+                                   , checker->vs->delay_loop);
+    return 0;
+  }
+
   if ( (fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1 ) {
 #ifdef _DEBUG_
     syslog(LOG_DEBUG, "TCP connect fail to create socket.");
index 7657d67..1da0f75 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Part:        check_tcp.c include file.
  *
- * Version:     $Id: check_tcp.h,v 0.5.9 2002/05/30 16:05:31 acassen Exp $
+ * Version:     $Id: check_tcp.h,v 0.6.1 2002/06/13 15:12:26 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
@@ -37,7 +37,6 @@ typedef struct _tcp_checker {
   int connection_to;
 } tcp_checker;
 
-
 /* Prototypes defs */
 extern void install_tcp_check_keyword(void);
 
index f3777df..3bcb72e 100755 (executable)
--- a/configure
+++ b/configure
@@ -18,6 +18,8 @@ ac_help="$ac_help
 ac_help="$ac_help
   --disable-vrrp          do not use the VRRP framework"
 ac_help="$ac_help
+  --with-ci_linux         Compile with Cluster Infrastructure support (default no)"
+ac_help="$ac_help
   --enable-debug          compile with debugging flags"
 
 # Initialize some variables set by options.
@@ -533,7 +535,7 @@ fi
 # Extract the first word of "gcc", so it can be a program name with args.
 set dummy gcc; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:537: checking for $ac_word" >&5
+echo "configure:539: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -563,7 +565,7 @@ if test -z "$CC"; then
   # Extract the first word of "cc", so it can be a program name with args.
 set dummy cc; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:567: checking for $ac_word" >&5
+echo "configure:569: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -614,7 +616,7 @@ fi
       # Extract the first word of "cl", so it can be a program name with args.
 set dummy cl; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:618: checking for $ac_word" >&5
+echo "configure:620: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -646,7 +648,7 @@ fi
 fi
 
 echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6
-echo "configure:650: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5
+echo "configure:652: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5
 
 ac_ext=c
 # CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
@@ -657,12 +659,12 @@ cross_compiling=$ac_cv_prog_cc_cross
 
 cat > conftest.$ac_ext << EOF
 
-#line 661 "configure"
+#line 663 "configure"
 #include "confdefs.h"
 
 main(){return(0);}
 EOF
-if { (eval echo configure:666: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:668: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   ac_cv_prog_cc_works=yes
   # If we can't run a trivial program, we are probably using a cross compiler.
   if (./conftest; exit) 2>/dev/null; then
@@ -688,12 +690,12 @@ if test $ac_cv_prog_cc_works = no; then
   { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; }
 fi
 echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6
-echo "configure:692: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5
+echo "configure:694: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5
 echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6
 cross_compiling=$ac_cv_prog_cc_cross
 
 echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6
-echo "configure:697: checking whether we are using GNU C" >&5
+echo "configure:699: checking whether we are using GNU C" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -702,7 +704,7 @@ else
   yes;
 #endif
 EOF
-if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:706: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
+if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:708: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
   ac_cv_prog_gcc=yes
 else
   ac_cv_prog_gcc=no
@@ -721,7 +723,7 @@ ac_test_CFLAGS="${CFLAGS+set}"
 ac_save_CFLAGS="$CFLAGS"
 CFLAGS=
 echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6
-echo "configure:725: checking whether ${CC-cc} accepts -g" >&5
+echo "configure:727: checking whether ${CC-cc} accepts -g" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -783,7 +785,7 @@ ac_configure=$ac_aux_dir/configure # This should be Cygnus configure.
 # SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
 # ./install, which can be erroneously created by make from ./install.sh.
 echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6
-echo "configure:787: checking for a BSD compatible install" >&5
+echo "configure:789: checking for a BSD compatible install" >&5
 if test -z "$INSTALL"; then
 if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -885,6 +887,14 @@ if test "${enable_vrrp+set}" = set; then
   :
 fi
 
+# Check whether --with-ci_linux or --without-ci_linux was given.
+if test "${with_ci_linux+set}" = set; then
+  withval="$with_ci_linux"
+  ci_linux=$withval
+else
+  ci_linux="no"
+fi
+
 # Check whether --enable-debug or --disable-debug was given.
 if test "${enable_debug+set}" = set; then
   enableval="$enable_debug"
@@ -908,6 +918,9 @@ fi
 if test "${enable_vrrp}" = "no"; then
   VRRP_SUPPORT="_WITHOUT_VRRP_"
 fi
+if test "${ci_linux}" = "yes"; then
+  CI_LINUX="_WITH_CI_LINUX_"
+fi
 if test "${enable_debug}" = "yes"; then
   DFLAGS="-D_DEBUG_"
   
@@ -917,6 +930,7 @@ fi
 
 
 
+
 IPVS_SYNCD="_WITHOUT_IPVS_SYNCD_"
 if test ${IPVS_MAJOR} -eq 0; then
   if test ${IPVS_MINOR} -eq 9; then
@@ -941,7 +955,7 @@ fi
 
 
 echo $ac_n "checking for MD5_Init in -lcrypto""... $ac_c" 1>&6
-echo "configure:945: checking for MD5_Init in -lcrypto" >&5
+echo "configure:959: checking for MD5_Init in -lcrypto" >&5
 ac_lib_var=`echo crypto'_'MD5_Init | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -949,7 +963,7 @@ else
   ac_save_LIBS="$LIBS"
 LIBS="-lcrypto  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 953 "configure"
+#line 967 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -960,7 +974,7 @@ int main() {
 MD5_Init()
 ; return 0; }
 EOF
-if { (eval echo configure:964: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:978: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -989,7 +1003,7 @@ else
 fi
 
 echo $ac_n "checking for SSL_CTX_new in -lssl""... $ac_c" 1>&6
-echo "configure:993: checking for SSL_CTX_new in -lssl" >&5
+echo "configure:1007: checking for SSL_CTX_new in -lssl" >&5
 ac_lib_var=`echo ssl'_'SSL_CTX_new | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -997,7 +1011,7 @@ else
   ac_save_LIBS="$LIBS"
 LIBS="-lssl  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 1001 "configure"
+#line 1015 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -1008,7 +1022,7 @@ int main() {
 SSL_CTX_new()
 ; return 0; }
 EOF
-if { (eval echo configure:1012: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:1026: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -1037,7 +1051,7 @@ else
 fi
 
 echo $ac_n "checking for poptGetContext in -lpopt""... $ac_c" 1>&6
-echo "configure:1041: checking for poptGetContext in -lpopt" >&5
+echo "configure:1055: checking for poptGetContext in -lpopt" >&5
 ac_lib_var=`echo popt'_'poptGetContext | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -1045,7 +1059,7 @@ else
   ac_save_LIBS="$LIBS"
 LIBS="-lpopt  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 1049 "configure"
+#line 1063 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -1056,7 +1070,7 @@ int main() {
 poptGetContext()
 ; return 0; }
 EOF
-if { (eval echo configure:1060: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:1074: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -1084,6 +1098,56 @@ else
 { echo "configure: error: Popt libraries is required" 1>&2; exit 1; }
 fi
 
+if test "${ci_linux}" = "yes"; then
+echo $ac_n "checking for cluster_maxnodes in -lcluster""... $ac_c" 1>&6
+echo "configure:1104: checking for cluster_maxnodes in -lcluster" >&5
+ac_lib_var=`echo cluster'_'cluster_maxnodes | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  ac_save_LIBS="$LIBS"
+LIBS="-lcluster  $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 1112 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+char cluster_maxnodes();
+
+int main() {
+cluster_maxnodes()
+; return 0; }
+EOF
+if { (eval echo configure:1123: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=yes"
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+    ac_tr_lib=HAVE_LIB`echo cluster | sed -e 's/[^a-zA-Z0-9_]/_/g' \
+    -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'`
+  cat >> confdefs.h <<EOF
+#define $ac_tr_lib 1
+EOF
+
+  LIBS="-lcluster $LIBS"
+
+else
+  echo "$ac_t""no" 1>&6
+{ echo "configure: error: libcluster libraries are required" 1>&2; exit 1; }
+fi
+
+fi
 
 if test "${KERNEL_CODE}" = "2"; then
   LIBFW="libipfwc/libipfwc.a"
@@ -1091,7 +1155,7 @@ if test "${KERNEL_CODE}" = "2"; then
     fi
 
 echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6
-echo "configure:1095: checking how to run the C preprocessor" >&5
+echo "configure:1159: checking how to run the C preprocessor" >&5
 # On Suns, sometimes $CPP names a directory.
 if test -n "$CPP" && test -d "$CPP"; then
   CPP=
@@ -1106,13 +1170,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 1110 "configure"
+#line 1174 "configure"
 #include "confdefs.h"
 #include <assert.h>
 Syntax Error
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:1116: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:1180: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
 if test -z "$ac_err"; then
   :
@@ -1123,13 +1187,13 @@ else
   rm -rf conftest*
   CPP="${CC-cc} -E -traditional-cpp"
   cat > conftest.$ac_ext <<EOF
-#line 1127 "configure"
+#line 1191 "configure"
 #include "confdefs.h"
 #include <assert.h>
 Syntax Error
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:1133: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:1197: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
 if test -z "$ac_err"; then
   :
@@ -1140,13 +1204,13 @@ else
   rm -rf conftest*
   CPP="${CC-cc} -nologo -E"
   cat > conftest.$ac_ext <<EOF
-#line 1144 "configure"
+#line 1208 "configure"
 #include "confdefs.h"
 #include <assert.h>
 Syntax Error
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:1150: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:1214: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
 if test -z "$ac_err"; then
   :
@@ -1171,12 +1235,12 @@ fi
 echo "$ac_t""$CPP" 1>&6
 
 echo $ac_n "checking for ANSI C header files""... $ac_c" 1>&6
-echo "configure:1175: checking for ANSI C header files" >&5
+echo "configure:1239: checking for ANSI C header files" >&5
 if eval "test \"`echo '$''{'ac_cv_header_stdc'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 1180 "configure"
+#line 1244 "configure"
 #include "confdefs.h"
 #include <stdlib.h>
 #include <stdarg.h>
@@ -1184,7 +1248,7 @@ else
 #include <float.h>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:1188: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:1252: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
 if test -z "$ac_err"; then
   rm -rf conftest*
@@ -1201,7 +1265,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 1205 "configure"
+#line 1269 "configure"
 #include "confdefs.h"
 #include <string.h>
 EOF
@@ -1219,7 +1283,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 1223 "configure"
+#line 1287 "configure"
 #include "confdefs.h"
 #include <stdlib.h>
 EOF
@@ -1240,7 +1304,7 @@ if test "$cross_compiling" = yes; then
   :
 else
   cat > conftest.$ac_ext <<EOF
-#line 1244 "configure"
+#line 1308 "configure"
 #include "confdefs.h"
 #include <ctype.h>
 #define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
@@ -1251,7 +1315,7 @@ if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) exit(2);
 exit (0); }
 
 EOF
-if { (eval echo configure:1255: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:1319: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
 then
   :
 else
@@ -1275,12 +1339,12 @@ EOF
 fi
 
 echo $ac_n "checking for sys/wait.h that is POSIX.1 compatible""... $ac_c" 1>&6
-echo "configure:1279: checking for sys/wait.h that is POSIX.1 compatible" >&5
+echo "configure:1343: checking for sys/wait.h that is POSIX.1 compatible" >&5
 if eval "test \"`echo '$''{'ac_cv_header_sys_wait_h'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 1284 "configure"
+#line 1348 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #include <sys/wait.h>
@@ -1296,7 +1360,7 @@ wait (&s);
 s = WIFEXITED (s) ? WEXITSTATUS (s) : 1;
 ; return 0; }
 EOF
-if { (eval echo configure:1300: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:1364: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   ac_cv_header_sys_wait_h=yes
 else
@@ -1320,17 +1384,17 @@ 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:1324: checking for $ac_hdr" >&5
+echo "configure:1388: checking for $ac_hdr" >&5
 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 1329 "configure"
+#line 1393 "configure"
 #include "confdefs.h"
 #include <$ac_hdr>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:1334: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:1398: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
 if test -z "$ac_err"; then
   rm -rf conftest*
@@ -1363,17 +1427,58 @@ 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:1367: checking for $ac_hdr" >&5
+echo "configure:1431: checking for $ac_hdr" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 1436 "configure"
+#include "confdefs.h"
+#include <$ac_hdr>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:1441: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+  rm -rf conftest*
+  eval "ac_cv_header_$ac_safe=yes"
+else
+  echo "$ac_err" >&5
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+    ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'`
+  cat >> confdefs.h <<EOF
+#define $ac_tr_hdr 1
+EOF
+else
+  echo "$ac_t""no" 1>&6
+fi
+done
+
+if test "${ci_linux}" = "yes"; then
+for ac_hdr in linux/cluster.h
+do
+ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
+echo "configure:1472: checking for $ac_hdr" >&5
 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 1372 "configure"
+#line 1477 "configure"
 #include "confdefs.h"
 #include <$ac_hdr>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:1377: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:1482: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
 if test -z "$ac_err"; then
   rm -rf conftest*
@@ -1396,17 +1501,19 @@ EOF
  
 else
   echo "$ac_t""no" 1>&6
+{ echo "configure: error: linux/cluster.h  file not found" 1>&2; exit 1; }
 fi
 done
 
+fi
 
 echo $ac_n "checking for working const""... $ac_c" 1>&6
-echo "configure:1405: checking for working const" >&5
+echo "configure:1512: checking for working const" >&5
 if eval "test \"`echo '$''{'ac_cv_c_const'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 1410 "configure"
+#line 1517 "configure"
 #include "confdefs.h"
 
 int main() {
@@ -1455,7 +1562,7 @@ ccp = (char const *const *) p;
 
 ; return 0; }
 EOF
-if { (eval echo configure:1459: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:1566: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   ac_cv_c_const=yes
 else
@@ -1476,12 +1583,12 @@ EOF
 fi
 
 echo $ac_n "checking for pid_t""... $ac_c" 1>&6
-echo "configure:1480: checking for pid_t" >&5
+echo "configure:1587: checking for pid_t" >&5
 if eval "test \"`echo '$''{'ac_cv_type_pid_t'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 1485 "configure"
+#line 1592 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #if STDC_HEADERS
@@ -1509,12 +1616,12 @@ EOF
 fi
 
 echo $ac_n "checking whether time.h and sys/time.h may both be included""... $ac_c" 1>&6
-echo "configure:1513: checking whether time.h and sys/time.h may both be included" >&5
+echo "configure:1620: checking whether time.h and sys/time.h may both be included" >&5
 if eval "test \"`echo '$''{'ac_cv_header_time'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 1518 "configure"
+#line 1625 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #include <sys/time.h>
@@ -1523,7 +1630,7 @@ int main() {
 struct tm *tp;
 ; return 0; }
 EOF
-if { (eval echo configure:1527: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:1634: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   ac_cv_header_time=yes
 else
@@ -1546,13 +1653,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:1550: checking whether ${CC-cc} needs -traditional" >&5
+echo "configure:1657: checking whether ${CC-cc} needs -traditional" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_gcc_traditional'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
     ac_pattern="Autoconf.*'x'"
   cat > conftest.$ac_ext <<EOF
-#line 1556 "configure"
+#line 1663 "configure"
 #include "confdefs.h"
 #include <sgtty.h>
 Autoconf TIOCGETP
@@ -1570,7 +1677,7 @@ rm -f conftest*
 
   if test $ac_cv_prog_gcc_traditional = no; then
     cat > conftest.$ac_ext <<EOF
-#line 1574 "configure"
+#line 1681 "configure"
 #include "confdefs.h"
 #include <termio.h>
 Autoconf TCGETA
@@ -1592,12 +1699,12 @@ echo "$ac_t""$ac_cv_prog_gcc_traditional" 1>&6
 fi
 
 echo $ac_n "checking return type of signal handlers""... $ac_c" 1>&6
-echo "configure:1596: checking return type of signal handlers" >&5
+echo "configure:1703: checking return type of signal handlers" >&5
 if eval "test \"`echo '$''{'ac_cv_type_signal'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 1601 "configure"
+#line 1708 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #include <signal.h>
@@ -1614,7 +1721,7 @@ int main() {
 int i;
 ; return 0; }
 EOF
-if { (eval echo configure:1618: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:1725: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   ac_cv_type_signal=void
 else
@@ -1635,12 +1742,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:1639: checking for $ac_func" >&5
+echo "configure:1746: checking for $ac_func" >&5
 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 1644 "configure"
+#line 1751 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char $ac_func(); below.  */
@@ -1663,7 +1770,7 @@ $ac_func();
 
 ; return 0; }
 EOF
-if { (eval echo configure:1667: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:1774: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_func_$ac_func=yes"
 else
@@ -1841,6 +1948,7 @@ s%@SYSTEM_SCRIPT_DIR@%$SYSTEM_SCRIPT_DIR%g
 s%@DFLAGS@%$DFLAGS%g
 s%@IPVS_SUPPORT@%$IPVS_SUPPORT%g
 s%@VRRP_SUPPORT@%$VRRP_SUPPORT%g
+s%@CI_LINUX@%$CI_LINUX%g
 s%@IPVS_SYNCD@%$IPVS_SYNCD%g
 s%@LIBFW@%$LIBFW%g
 s%@LIBOBJS@%$LIBOBJS%g
@@ -1997,6 +2105,11 @@ if test "${VRRP_SUPPORT}" = "_WITH_VRRP_"; then
 else
   echo "Use VRRP Framework       : No"
 fi
+if test "${CI_LINUX}" = "_WITH_CI_LINUX_"; then
+  echo "Use CI_LINUX Framework   : Yes"
+else
+  echo "Use CI_LINUX Framework   : No"
+fi
 if test "${DFLAGS}" = "-D_DEBUG_"; then
   echo "Use Debug flags          : Yes"
 else
index cff3bef..aa2a7df 100644 (file)
@@ -54,6 +54,9 @@ AC_ARG_ENABLE(lvs,
   [  --disable-lvs           do not use the LVS framework])
 AC_ARG_ENABLE(vrrp,
   [  --disable-vrrp          do not use the VRRP framework])
+AC_ARG_WITH(ci_linux,
+  [  --with-ci_linux         Compile with Cluster Infrastructure support (default no)],
+  ci_linux=$withval,ci_linux="no")
 AC_ARG_ENABLE(debug,
   [  --enable-debug          compile with debugging flags])
 
@@ -73,6 +76,9 @@ fi
 if test "${enable_vrrp}" = "no"; then
   VRRP_SUPPORT="_WITHOUT_VRRP_"
 fi
+if test "${ci_linux}" = "yes"; then
+  CI_LINUX="_WITH_CI_LINUX_"
+fi
 if test "${enable_debug}" = "yes"; then
   DFLAGS="-D_DEBUG_"
   AC_SUBST(DFLAGS)
@@ -80,6 +86,7 @@ fi
 
 AC_SUBST(IPVS_SUPPORT)
 AC_SUBST(VRRP_SUPPORT)
+AC_SUBST(CI_LINUX)
 
 dnl ----[ LVS syncd support probe ]---
 dnl Sync daemon is supported since LVS 0.9.2 for kernel 2.4
@@ -111,6 +118,9 @@ dnl ----[ Checks for libraries ]----
 AC_CHECK_LIB(crypto, MD5_Init,,AC_MSG_ERROR([OpenSSL libraries are required]))
 AC_CHECK_LIB(ssl, SSL_CTX_new,,AC_MSG_ERROR([OpenSSL libraries are required]))
 AC_CHECK_LIB(popt, poptGetContext,,AC_MSG_ERROR([Popt libraries is required]))
+if test "${ci_linux}" = "yes"; then
+AC_CHECK_LIB(cluster,cluster_maxnodes,,AC_MSG_ERROR([libcluster libraries are required]))
+fi
 
 dnl ----[ Create object list ]----
 if test "${KERNEL_CODE}" = "2"; then
@@ -127,6 +137,9 @@ 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)
+if test "${ci_linux}" = "yes"; then
+AC_CHECK_HEADERS(linux/cluster.h,,AC_MSG_ERROR([linux/cluster.h  file not found]))
+fi
 
 dnl ----[ Checks for typedefs, structures, and compiler characteristics ]----
 AC_C_CONST
@@ -181,6 +194,11 @@ if test "${VRRP_SUPPORT}" = "_WITH_VRRP_"; then
 else
   echo "Use VRRP Framework       : No"
 fi
+if test "${CI_LINUX}" = "_WITH_CI_LINUX_"; then
+  echo "Use CI_LINUX Framework   : Yes"
+else
+  echo "Use CI_LINUX Framework   : No"
+fi
 if test "${DFLAGS}" = "-D_DEBUG_"; then
   echo "Use Debug flags          : Yes"
 else
index cc63642..8f7dc64 100644 (file)
--- a/daemon.c
+++ b/daemon.c
@@ -5,7 +5,7 @@
  *
  * Part:        Main program structure.
  *
- * Version:     $Id: main.c,v 0.5.9 2002/05/30 16:05:31 acassen Exp $
+ * Version:     $Id: main.c,v 0.6.1 2002/06/13 15:12:26 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
index 89ff3c8..a17f9fa 100644 (file)
--- a/daemon.h
+++ b/daemon.h
@@ -5,7 +5,7 @@
  *
  * Part:        Daemon process handling.
  *
- * Version:     $Id: daemon.h,v 0.5.9 2002/05/30 16:05:31 acassen Exp $
+ * Version:     $Id: daemon.h,v 0.6.1 2002/06/13 15:12:26 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
diff --git a/data.c b/data.c
index 495f68e..10c746f 100644 (file)
--- a/data.c
+++ b/data.c
@@ -5,7 +5,7 @@
  *
  * Part:        Dynamic data structure definition.
  *
- * Version:     $Id: data.c,v 0.5.9 2002/05/30 16:05:31 acassen Exp $
+ * Version:     $Id: data.c,v 0.6.1 2002/06/13 15:12:26 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
@@ -25,6 +25,7 @@
 #include "utils.h"
 #include "check_api.h"
 #include "vrrp.h"
+#include "vrrp_sync.h"
 
 extern data *conf_data;
 
@@ -83,12 +84,34 @@ static void dump_ssl(void)
 }
 
 /* VRRP facility functions */
+static void free_vgroup(void *data)
+{
+  vrrp_sgroup *vgroup = data;
+
+  FREE(vgroup->gname);
+  free_strvec(vgroup->iname);
+  FREE(vgroup);
+}
+static void dump_vgroup(void *data)
+{
+  vrrp_sgroup *vgroup = data;
+  int i;
+  char *str;
+
+  syslog(LOG_INFO, " VRRP Sync Group = %s, %s"
+                 , vgroup->gname
+                 , (vgroup->state == VRRP_STATE_MAST)?"MASTER":"BACKUP");
+  for (i = 0; i < VECTOR_SIZE(vgroup->iname); i++) {
+    str = VECTOR_SLOT(vgroup->iname, i);
+    syslog(LOG_INFO, "   monitor = %s", str);
+  }
+}
+
 static void free_vrrp(void *data)
 {
   vrrp_rt *vrrp = data;
 
   FREE(vrrp->iname);
-  FREE_PTR(vrrp->isync);
   FREE_PTR(vrrp->lvs_syncd_if);
   FREE_PTR(vrrp->vaddr);
   FREE_PTR(vrrp->evaddr);
@@ -104,13 +127,14 @@ static void dump_vrrp(void *data)
   int i;
 
   syslog(LOG_INFO, " VRRP Instance = %s", vrrp->iname);
-  if (vrrp->isync)
-    syslog(LOG_INFO, "   Sync with instance = %s", vrrp->isync);
   if (vrrp->init_state == VRRP_STATE_BACK)
     syslog(LOG_INFO, "   Want State = BACKUP");
   else
     syslog(LOG_INFO, "   Want State = MASTER");
   syslog(LOG_INFO, "   Runing on device = %s", IF_NAME(vrrp->ifp));
+  if (vrrp->mcast_saddr)
+    syslog(LOG_INFO, "   Using mcast src_ip = %s"
+                   , ip_ntoa(vrrp->mcast_saddr));
   if (vrrp->lvs_syncd_if)
     syslog(LOG_INFO, "   Runing LVS sync daemon on interface = %s"
                    , vrrp->lvs_syncd_if);
@@ -126,11 +150,13 @@ static void dump_vrrp(void *data)
   }
   syslog(LOG_INFO, "   VIP count = %d", vrrp->naddr);
   for (i = 0; i < vrrp->naddr; i++)
-    syslog(LOG_INFO, "     VIP%d = %s", i+1, ip_ntoa(vrrp->vaddr[i].addr));
+    syslog(LOG_INFO, "     VIP%d = %s/%d", i+1, ip_ntoa(vrrp->vaddr[i].addr)
+                                              , vrrp->vaddr[i].mask);
   if (vrrp->neaddr) {
     syslog(LOG_INFO, "   Excluded VIP count = %d", vrrp->neaddr);
     for (i = 0; i < vrrp->neaddr; i++)
-      syslog(LOG_INFO, "     E-VIP%d = %s", i+1, ip_ntoa(vrrp->evaddr[i].addr));
+      syslog(LOG_INFO, "     E-VIP%d = %s/%d", i+1, ip_ntoa(vrrp->evaddr[i].addr)
+                                                  , vrrp->evaddr[i].mask);
   }
   if (vrrp->script_backup)
     syslog(LOG_INFO, "   Backup state transition script = %s"
@@ -144,6 +170,19 @@ static void dump_vrrp(void *data)
   if (vrrp->smtp_alert)
     syslog(LOG_INFO, "   Using smtp notification");
 }
+void alloc_vrrp_sync_group(char *gname, vector iname)
+{
+  int size = strlen(gname);
+  vrrp_sgroup *new;
+
+  /* Allocate new VRRP group structure */
+  new = (vrrp_sgroup *)MALLOC(sizeof(vrrp_sgroup));
+  new->gname = (char *)MALLOC(size+1);
+  memcpy(new->gname, gname, size);
+  new->iname = iname;
+
+  list_add(conf_data->vrrp_sync_group, new);
+}
 void alloc_vrrp(char *iname)
 {
   int size = strlen(iname);
@@ -163,13 +202,15 @@ void alloc_vrrp(char *iname)
   new->adver_int  = TIMER_HZ;
   new->iname      = (char *)MALLOC(size+1);
   memcpy(new->iname, iname, size);
+  new->sync = vrrp_get_sync_group(iname);
 
   list_add(conf_data->vrrp, new);
 }
 void alloc_vrrp_vip(char *vip)
 {
   vrrp_rt *vrrp = LIST_TAIL_DATA(conf_data->vrrp);
-  uint32_t ipaddr = inet_addr(vip);
+  uint32_t ipaddr = ip_ston(vip);
+  uint8_t mask = ip_stom(vip);
 
   vrrp->naddr++;
   if (vrrp->vaddr)
@@ -177,12 +218,14 @@ void alloc_vrrp_vip(char *vip)
   else
     vrrp->vaddr = (vip_addr *)MALLOC(sizeof(*vrrp->vaddr));
   vrrp->vaddr[vrrp->naddr-1].addr = ipaddr;
+  vrrp->vaddr[vrrp->naddr-1].mask = mask;
   vrrp->vaddr[vrrp->naddr-1].set  = 0;
 }
 void alloc_vrrp_evip(char *vip)
 {
   vrrp_rt *vrrp = LIST_TAIL_DATA(conf_data->vrrp);
-  uint32_t ipaddr = inet_addr(vip);
+  uint32_t ipaddr = ip_ston(vip);
+  uint8_t mask = ip_stom(vip);
 
   vrrp->neaddr++;
   if (vrrp->evaddr)
@@ -190,6 +233,7 @@ void alloc_vrrp_evip(char *vip)
   else
     vrrp->evaddr = (vip_addr *)MALLOC(sizeof(*vrrp->evaddr));
   vrrp->evaddr[vrrp->neaddr-1].addr = ipaddr;
+  vrrp->evaddr[vrrp->neaddr-1].mask = mask;
   vrrp->evaddr[vrrp->neaddr-1].set  = 0;
 }
 
@@ -408,6 +452,7 @@ data *alloc_data(void)
   new = (data *)MALLOC(sizeof(data));
   new->email = alloc_list(free_email, dump_email);
   new->vrrp  = alloc_list(free_vrrp,  dump_vrrp);
+  new->vrrp_sync_group  = alloc_list(free_vgroup,  dump_vgroup);
   new->vs    = alloc_list(free_vs,    dump_vs);
   new->group = alloc_list(free_group, dump_group);
 
@@ -418,6 +463,7 @@ void free_data(void)
   free_ssl();
   free_list(conf_data->email);
   free_list(conf_data->vrrp);
+  free_list(conf_data->vrrp_sync_group);
   free_list(conf_data->vs);
   free_list(conf_data->group);
 
@@ -453,6 +499,10 @@ void dump_data(void)
     syslog(LOG_INFO, "------< VRRP Topology >------");
     dump_list(conf_data->vrrp);
   }
+  if (!LIST_ISEMPTY(conf_data->vrrp_sync_group)) {
+    syslog(LOG_INFO, "------< VRRP Sync groups >------");
+    dump_list(conf_data->vrrp_sync_group);
+  }
   if (!LIST_ISEMPTY(conf_data->group)) {
     syslog(LOG_INFO, "------< Real Servers groups >------");
     dump_list(conf_data->group);
diff --git a/data.h b/data.h
index 4ab284c..9c88cd4 100644 (file)
--- a/data.h
+++ b/data.h
@@ -5,7 +5,7 @@
  *
  * Part:        Dynamic data structure definition.
  *
- * Version:     $Id: data.h,v 0.5.9 2002/05/30 16:05:31 acassen Exp $
+ * Version:     $Id: data.h,v 0.6.1 2002/06/13 15:12:26 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
@@ -46,6 +46,7 @@
 
 /* local includes */
 #include "list.h"
+#include "vector.h"
 
 /* Daemon dynamic data structure definition */
 #define MAX_TIMEOUT_LENGTH     5
@@ -114,6 +115,7 @@ typedef struct _data {
   SSL_DATA     *ssl;
   list         email;
   list         vrrp;
+  list         vrrp_sync_group;
   list         vs;
   list         group;
 } data;
@@ -128,6 +130,7 @@ typedef struct _data {
 /* prototypes */
 extern void alloc_email(char *addr);
 extern SSL_DATA *alloc_ssl(void);
+extern void alloc_vrrp_sync_group(char *gname, vector iname);
 extern void alloc_vrrp(char *iname);
 extern void alloc_vrrp_vip(char *vip);
 extern void alloc_vrrp_evip(char *vip);
index 282d238..9e5a035 100755 (executable)
@@ -6,6 +6,9 @@
 # pidfile: /var/run/keepalived.pid
 # config: /etc/keepalived/keepalived.conf
 
+# Global definitions
+PID_FILE="/var/run/keepalived.pid"
+
 # See how we were called.
 case "$1" in
   start)
@@ -15,7 +18,7 @@ case "$1" in
        ;;
   stop)
        echo -n "Shutting down Keepalived for LVS: "
-       PID=`ps ax | grep keepalived | awk '{print $1}'`
+       PID=`cat $PID_FILE`
        kill $PID
        echo
        ;;
index 2e422ff..6891dec 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.9 2002/05/30 16:05:31 acassen Exp $
+ * Version:     $Id: ipfwwrapper.c,v 0.6.1 2002/06/13 15:12:26 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
index f765538..719dca9 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Part:        ipfwwrapper.c include file.
  *
- * Version:     $Id: ipfwwrapper.h,v 0.5.9 2002/05/30 16:05:31 acassen Exp $
+ * Version:     $Id: ipfwwrapper.h,v 0.6.1 2002/06/13 15:12:26 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
index df4c903..0efa6cd 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.9 2002/05/30 16:05:31 acassen Exp $
+ * Version:     $Id: ipvswrapper.c,v 0.6.1 2002/06/13 15:12:26 acassen Exp $
  * 
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *              
index dc0a4ad..7754cce 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Part:        ipvswrapper.c include file.
  *
- * Version:     $Id: ipvswrapper.h,v 0.5.9 2002/05/30 16:05:31 acassen Exp $
+ * Version:     $Id: ipvswrapper.h,v 0.6.1 2002/06/13 15:12:26 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
index 877fe0b..2dc3385 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Part:        Manipulation functions for IPVS & IPFW wrappers.
  *
- * Version:     $id: ipwrapper.c,v 0.5.9 2002/05/30 16:05:31 acassen Exp $
+ * Version:     $id: ipwrapper.c,v 0.6.1 2002/06/13 15:12:26 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
index 2f3593c..6cfab7a 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Part:        ipwrapper.c include file.
  *
- * Version:     $Id: ipwrapper.h,v 0.5.9 2002/05/30 16:05:31 acassen Exp $
+ * Version:     $Id: ipwrapper.h,v 0.6.1 2002/06/13 15:12:26 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
index 2dbb383..512557e 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.9 2002/05/30 16:05:31 acassen Exp $
+ * Version:     $Id: layer4.c,v 0.6.1 2002/06/13 15:12:26 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
index 481a293..6c8235e 100644 (file)
--- a/layer4.h
+++ b/layer4.h
@@ -5,7 +5,7 @@
  *
  * Part:        layer4.c include file.
  *
- * Version:     $Id: layer4.h,v 0.5.9 2002/05/30 16:05:31 acassen Exp $
+ * Version:     $Id: layer4.h,v 0.6.1 2002/06/13 15:12:26 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
diff --git a/list.c b/list.c
index 8dbb7c2..53adb80 100644 (file)
--- a/list.c
+++ b/list.c
@@ -5,7 +5,7 @@
  * 
  * Part:        List structure manipulation.
  *  
- * Version:     $Id: list.c,v 0.5.9 2002/05/30 16:05:31 acassen Exp $
+ * Version:     $Id: list.c,v 0.6.1 2002/06/13 15:12:26 acassen Exp $
  * 
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *              
diff --git a/list.h b/list.h
index d5daba2..c755f47 100644 (file)
--- a/list.h
+++ b/list.h
@@ -5,7 +5,7 @@
  * 
  * Part:        list.c include file.
  *  
- * Version:     $Id: list.h,v 0.5.9 2002/05/30 16:05:31 acassen Exp $
+ * Version:     $Id: list.h,v 0.6.1 2002/06/13 15:12:26 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
diff --git a/main.c b/main.c
index 0f4f39d..131e307 100644 (file)
--- a/main.c
+++ b/main.c
@@ -5,7 +5,7 @@
  *
  * Part:        Main program structure.
  *
- * Version:     $Id: main.c,v 0.5.9 2002/05/30 16:05:31 acassen Exp $
+ * Version:     $Id: main.c,v 0.6.1 2002/06/13 15:12:26 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
@@ -221,7 +221,6 @@ int main(int argc, char **argv)
 #ifdef _WITH_LVS_
   init_checkers_queue();
 #endif
-  init_keywords();
   init_data(conf_file);
   if (!conf_data) {
     syslog(LOG_INFO, "Stopping "VERSION_STRING);
@@ -268,7 +267,7 @@ int main(int argc, char **argv)
   register_vrrp_thread();
 
   /* processing the master thread queues, return and execute one ready thread */
-  while(thread_fetch(master, &thread)) {
+  while (thread_fetch(master, &thread)) {
 
     /* Run until error, used for debuging only */
 #ifdef _DEBUG_
diff --git a/main.h b/main.h
index 2cbc2c0..60bfcef 100644 (file)
--- a/main.h
+++ b/main.h
@@ -5,7 +5,7 @@
  *
  * Part:        Main program include file.
  *
- * Version:     $Id: main.h,v 0.5.9 2002/05/30 16:05:31 acassen Exp $
+ * Version:     $Id: main.h,v 0.6.1 2002/06/13 15:12:26 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
@@ -43,7 +43,7 @@
 #include "vrrp_netlink.h"
 
 /* global var */
-thread_master *master;
+thread_master *master = NULL;
 unsigned int debug;
 unsigned long mem_allocated = 0;
 data *conf_data;
@@ -58,8 +58,8 @@ extern void register_vrrp_thread(void);
 /* Build version */
 #define PROG    "Keepalived"
 
-#define VERSION_CODE 0x000509
-#define DATE_CODE    0x1E0502
+#define VERSION_CODE 0x000601
+#define DATE_CODE    0x0D0602
 
 #define KEEPALIVED_VERSION(version)    \
        (version >> 16) & 0xFF,         \
index 3af98f8..be22455 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.9 2002/05/30 16:05:31 acassen Exp $
+ * Version:     $Id: memory.c,v 0.6.1 2002/06/13 15:12:26 acassen Exp $
  *
  * Authors:     Alexandre Cassen, <acassen@linux-vs.org>
  *              Jan Holmberg, <jan@artech.net>
 void *xalloc(unsigned long size)
 {
   void *mem;
+  if ((mem = malloc(size)))
+    mem_allocated += size;
+  return mem;
+}
+void *zalloc(unsigned long size)
+{
+  void *mem;
   if ((mem = malloc(size))) {
     memset(mem, 0, size);
     mem_allocated += size;
@@ -107,7 +114,7 @@ char *keepalived_malloc(unsigned long size, char *file, char *function, int line
   int i = 0;
   long check;
 
-  buf = xalloc(size+sizeof(long)) ;
+  buf = zalloc(size + sizeof(long));
 
   check =  0xa5a5 + size;
   *(long *)((char *)buf+size) = check;
@@ -130,7 +137,7 @@ char *keepalived_malloc(unsigned long size, char *file, char *function, int line
   alloc_list[i].type = 9;
 
   if (debug & 1)
-    printf("%sxalloc[%3d:%3d], %p, %4ld at %s, %3d, %s\n"
+    printf("%szalloc[%3d:%3d], %p, %4ld at %s, %3d, %s\n"
            ,nspace(s++), i, number_alloc_list, buf, size, file, line, function);
 
   n++;
@@ -328,7 +335,7 @@ void *keepalived_realloc(void * buffer, unsigned long size, char *file, char* fu
 
   /* not found */
   if (i == number_alloc_list) {
-    printf("realloc ERROR no matching xalloc %p \n", buffer);
+    printf("realloc ERROR no matching zalloc %p \n", buffer);
     number_alloc_list++;
     alloc_list[i].ptr  = buf;
     alloc_list[i].size = 0;
index 39508b4..cf9149c 100644 (file)
--- a/memory.h
+++ b/memory.h
@@ -5,7 +5,7 @@
  *
  * Part:        memory.c include file.
  *
- * Version:     $Id: memory.h,v 0.5.9 2002/05/30 16:05:31 acassen Exp $
+ * Version:     $Id: memory.h,v 0.6.1 2002/06/13 15:12:26 acassen Exp $
  *
  * Authors:     Alexandre Cassen, <acassen@linux-vs.org>
  *              Jan Holmberg, <jan@artech.net>
 extern unsigned int debug;
 extern unsigned long mem_allocated;
 extern void *xalloc(unsigned long size);
+extern void *zalloc(unsigned long size);
 extern void xfree(void *p);
 
+/* Global alloc macro */
+#define ALLOC(n) (xalloc(n))
+
 /* Local defines */
 #ifdef _DEBUG_
 
@@ -54,7 +58,7 @@ extern void keepalived_free_final(void);
 
 #else
 
-#define MALLOC(n)    (xalloc(n))
+#define MALLOC(n)    (zalloc(n))
 #define FREE(p)      (xfree(p))
 #define REALLOC(p,n) (realloc((p),(n)))
 
index 9120586..5974c2c 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.9 2002/05/30 16:05:31 acassen Exp $
+ * Version:     $Id: parser.c,v 0.6.1 2002/06/13 15:12:26 acassen Exp $
  * 
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *              
@@ -110,40 +110,6 @@ static void free_keywords(vector keywords)
   vector_free(keywords);
 }
 
-/*
-static void dump_strvec(vector strvec)
-{
-  int i;
-  char *str;
-
-  if (!strvec)
-    return;
-
-  printf("String Vector : ");
-
-  for (i = 0; i < VECTOR_SIZE(strvec); i++) {
-    str = VECTOR_SLOT(strvec, i);
-    printf("[%i]=%s ", i, str);
-  }
-  printf("\n");
-}
-*/
-
-static void free_strvec(vector strvec)
-{
-  int i;
-  char *str;
-
-  if (!strvec)
-    return;
-
-  for (i=0; i < VECTOR_SIZE(strvec); i++)
-    if ((str = VECTOR_SLOT(strvec, i)) != NULL)
-      FREE(str);
-
-  vector_free(strvec);
-}
-
 static vector alloc_strvec(char *string)
 {
   char *cp, *start, *token;
@@ -332,19 +298,20 @@ static void sslkey_handler(vector strvec)
 }
 
 /* VRRP handlers */
-static void vrrp_handler(vector strvec)
+static void vrrp_sync_group_handler(vector strvec)
 {
-  alloc_vrrp(VECTOR_SLOT(strvec, 1));
+  vector iname = read_value_block();
+  alloc_vrrp_sync_group(VECTOR_SLOT(strvec, 1), iname);
 }
-static void vrrp_isync_handler(vector strvec)
+static void vrrp_handler(vector strvec)
 {
-  vrrp_rt *vrrp = LIST_TAIL_DATA(conf_data->vrrp);
-  vrrp->isync = set_value(strvec);
+  alloc_vrrp(VECTOR_SLOT(strvec, 1));
 }
 static void vrrp_state_handler(vector strvec)
 {
   char *str = VECTOR_SLOT(strvec, 1);
   vrrp_rt *vrrp = LIST_TAIL_DATA(conf_data->vrrp);
+  vrrp_sgroup *vgroup = vrrp->sync;
 
   if (!strcmp(str, "MASTER")) {
     vrrp->wantstate  = VRRP_STATE_MAST;
@@ -353,6 +320,10 @@ static void vrrp_state_handler(vector strvec)
     vrrp->wantstate  = VRRP_STATE_BACK;
     vrrp->init_state = VRRP_STATE_BACK;
   }
+
+  /* set eventual sync group */
+  if (vgroup)
+    vgroup->state = vrrp->wantstate;
 }
 static void vrrp_int_handler(vector strvec)
 {
@@ -361,6 +332,11 @@ static void vrrp_int_handler(vector strvec)
 
   vrrp->ifp = if_get_by_ifname(name);
 }
+static void vrrp_mcastip_handler(vector strvec)
+{
+  vrrp_rt *vrrp = LIST_TAIL_DATA(conf_data->vrrp);
+  vrrp->mcast_saddr = inet_addr(VECTOR_SLOT(strvec, 1));
+}
 static void vrrp_vrid_handler(vector strvec)
 {
   vrrp_rt *vrrp = LIST_TAIL_DATA(conf_data->vrrp);
@@ -676,15 +652,16 @@ void init_keywords(void)
   install_keyword("key",                       &sslkey_handler);
 
   /* VRRP Instance mapping */
+  install_keyword_root("vrrp_sync_group",      &vrrp_sync_group_handler);
   install_keyword_root("vrrp_instance",                &vrrp_handler);
   install_keyword("state",                     &vrrp_state_handler);
   install_keyword("interface",                 &vrrp_int_handler);
+  install_keyword("mcast_src_ip",              &vrrp_mcastip_handler);
   install_keyword("virtual_router_id",         &vrrp_vrid_handler);
   install_keyword("priority",                  &vrrp_prio_handler);
   install_keyword("advert_int",                        &vrrp_adv_handler);
   install_keyword("virtual_ipaddress",         &vrrp_vip_handler);
   install_keyword("virtual_ipaddress_excluded",        &vrrp_evip_handler);
-  install_keyword("sync_instance",             &vrrp_isync_handler);
   install_keyword("preempt",                   &vrrp_preempt_handler);
   install_keyword("debug",                     &vrrp_debug_handler);
   install_keyword("notify_backup",             &vrrp_notify_backup_handler);
@@ -744,6 +721,9 @@ void init_data(char *conf_file)
     return;
   }
 
+  /* Init Keywords structure */
+  init_keywords();
+
   /* Init data structure */
   conf_data = alloc_data();
 
index cd8d084..9d987ea 100644 (file)
--- a/parser.h
+++ b/parser.h
@@ -5,7 +5,7 @@
  * 
  * Part:        cfreader.c include file.
  *  
- * Version:     $Id: parser.h,v 0.5.9 2002/05/30 16:05:31 acassen Exp $
+ * Version:     $Id: parser.h,v 0.6.1 2002/06/13 15:12:26 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
index 5d4a365..8f57d62 100644 (file)
--- a/pidfile.c
+++ b/pidfile.c
@@ -5,7 +5,7 @@
  *
  * Part:        pidfile utility.
  *
- * Version:     $Id: pidfile.c,v 0.5.9 2002/05/30 16:05:31 acassen Exp $
+ * Version:     $Id: pidfile.c,v 0.6.1 2002/06/13 15:12:26 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
index 06f4164..c4e2f6d 100644 (file)
--- a/pidfile.h
+++ b/pidfile.h
@@ -5,7 +5,7 @@
  *
  * Part:        pidfile.c include file.
  *
- * Version:     $Id: pidfile.h,v 0.5.9 2002/05/30 16:05:31 acassen Exp $
+ * Version:     $Id: pidfile.h,v 0.6.1 2002/06/13 15:12:26 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
index 59ba1d6..01d4200 100644 (file)
 ! Configuration File for keepalived
 
-global_defs {
-   notification_email {
-     acassen@canal-plus.com
-   }
-   notification_email_from keepalived@canal-plus.com
-   smtp_server 172.31.47.6
-   smtp_connect_timeout 30
-   lvs_id LVS_DEVEL
+vrrp_sync_group G1 {
+  VI_1
+  VI_2
+  VI_5
+  VI_6
+  VI_7
+  VI_8
+  VI_9
+}
+
+vrrp_sync_group G2 {
+  VI_3
+  VI_4
 }
 
 vrrp_instance VI_1 {
-    state MASTER
     interface eth0
+    state MASTER
     virtual_router_id 51
-    priority 150
-    advert_int 1
-    authentication {
-        auth_type AH
-        auth_pass 1111
-    }
+    priority 100
     virtual_ipaddress {
-        192.168.200.16
-        192.168.200.17
-        192.168.200.18
+        192.168.200.18/25
     }
 }
 
 vrrp_instance VI_2 {
-    interface eth0
+    interface eth1
+    state MASTER
     virtual_router_id 52
     priority 100
-    advert_int 1
     virtual_ipaddress {
-        192.168.200.19
-        192.168.200.20
-        192.168.200.21
+        192.168.201.18/26
     }
-    sync_instance VI_3
 }
 
 vrrp_instance VI_3 {
-    interface eth1
+    interface eth0
     virtual_router_id 53
     priority 100
-    advert_int 1
     virtual_ipaddress {
-        192.168.201.19
-        192.168.201.20
-        192.168.201.21
+        192.168.200.19/27
+    }
+}
+
+vrrp_instance VI_4 {
+    interface eth1
+    virtual_router_id 54
+    priority 100
+    virtual_ipaddress {
+        192.168.201.19/28
+    }
+}
+
+vrrp_instance VI_5 {
+    state MASTER
+    interface eth0
+    virtual_router_id 55
+    priority 100
+    virtual_ipaddress {
+        192.168.200.20/27
+    }
+}
+
+
+vrrp_instance VI_6 {
+    state MASTER
+    interface eth0
+    virtual_router_id 56
+    priority 100
+    virtual_ipaddress {
+        192.168.200.21/27
     }
-    sync_instance VI_2
 }
 
-virtual_server 192.168.200.19 80 {
-    delay_loop 20
-    lb_algo rr
-    lb_kind NAT
-    nat_mask 255.255.255.0
-    persistence_timeout 50
-    protocol TCP
+vrrp_instance VI_7 {
+    state MASTER
+    interface eth0
+    virtual_router_id 57
+    priority 100
+    virtual_ipaddress {
+        192.168.200.22/27
+    }
+}
 
-    real_server 192.168.201.100 80 {
-        weight 1
-        TCP_CHECK {
-            connect_timeout 3
-        }
+vrrp_instance VI_8 {
+    state MASTER
+    interface eth0
+    virtual_router_id 58
+    priority 100
+    virtual_ipaddress {
+        192.168.200.23/27
+    }
+}
+
+vrrp_instance VI_9 {
+    state MASTER
+    interface eth0
+    virtual_router_id 59
+    priority 100
+    virtual_ipaddress {
+        192.168.200.24/27
     }
 }
+
index 3afcba1..7c2b0ae 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.9 2002/05/30 16:05:31 acassen Exp $
+ * Version:     $Id: scheduler.c,v 0.6.1 2002/06/13 15:12:26 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
index 27a97d3..547c369 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Part:        scheduler.c include file.
  *
- * Version:     $Id: scheduler.h,v 0.5.9 2002/05/30 16:05:31 acassen Exp $
+ * Version:     $Id: scheduler.h,v 0.6.1 2002/06/13 15:12:26 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
diff --git a/smtp.c b/smtp.c
index 803e458..5569dd2 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.9 2002/05/30 16:05:31 acassen Exp $
+ * Version:     $Id: smtp.c,v 0.6.1 2002/06/13 15:12:26 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
diff --git a/smtp.h b/smtp.h
index 4d664d6..656443a 100644 (file)
--- a/smtp.h
+++ b/smtp.h
@@ -5,7 +5,7 @@
  *
  * Part:        smtp.c include file.
  *
- * Version:     $Id: smtp.h,v 0.5.9 2002/05/30 16:05:31 acassen Exp $
+ * Version:     $Id: smtp.h,v 0.6.1 2002/06/13 15:12:26 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
diff --git a/timer.c b/timer.c
index 8f6c7ae..c89d0e9 100644 (file)
--- a/timer.c
+++ b/timer.c
@@ -5,7 +5,7 @@
  * 
  * Part:        Timer manipulations.
  *  
- * Version:     $Id: timer.c,v 0.5.9 2002/05/30 16:05:31 acassen Exp $
+ * Version:     $Id: timer.c,v 0.6.1 2002/06/13 15:12:26 acassen Exp $
  * 
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *              
diff --git a/timer.h b/timer.h
index 03f70f0..0419ca0 100644 (file)
--- a/timer.h
+++ b/timer.h
@@ -5,7 +5,7 @@
  * 
  * Part:        timer.c include file.
  *  
- * Version:     $Id: timer.h,v 0.5.9 2002/05/30 16:05:31 acassen Exp $
+ * Version:     $Id: timer.h,v 0.6.1 2002/06/13 15:12:26 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
diff --git a/utils.c b/utils.c
index 6e41620..e3ea50b 100644 (file)
--- a/utils.c
+++ b/utils.c
@@ -5,7 +5,7 @@
  *
  * Part:        General program utils.
  *
- * Version:     $Id: utils.c,v 0.5.9 2002/05/30 16:05:31 acassen Exp $
+ * Version:     $Id: utils.c,v 0.6.1 2002/06/13 15:12:26 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
@@ -22,6 +22,7 @@
 
 #include "utils.h"
 
+/* Display a buffer into a HEXA formated output */
 void print_buffer(int count, char *buff)
 {
   int i,j,c;
@@ -60,12 +61,41 @@ void print_buffer(int count, char *buff)
   }
 }
 
+/* IP network to ascii representation */
 char *ip_ntoa(uint32_t ip)
 {
-  static char buf[20];
+  static char buf[16];
   unsigned char *bytep;
 
   bytep = (unsigned char *) &(ip);
   sprintf(buf, "%d.%d.%d.%d", bytep[0], bytep[1], bytep[2], bytep[3]);
   return buf;
 }
+
+/* IP string to network representation */
+uint32_t ip_ston(char *addr)
+{
+  char *cp = addr;
+  static char buf[16];
+  int strlen;
+
+  while (*cp != '/' && *cp != '\0')
+    cp++;
+  strlen = cp - addr;
+  memcpy(buf, addr, strlen);
+  buf[strlen + 1] = '\0';
+  return inet_addr(buf);
+}
+
+/* IP string to network mask representation */
+uint8_t ip_stom(char *addr)
+{
+  uint8_t mask = 32;
+  char *cp = addr;
+
+  while (*cp != '/' && *cp != '\0')
+    cp++;
+  if (*cp == '/')
+    return atoi(++cp);
+  return mask;
+}
diff --git a/utils.h b/utils.h
index ab07a1d..32d19e3 100644 (file)
--- a/utils.h
+++ b/utils.h
@@ -5,7 +5,7 @@
  *
  * Part:        utils.h include file.
  *
- * Version:     $Id: utils.h,v 0.5.9 2002/05/30 16:05:31 acassen Exp $
+ * Version:     $Id: utils.h,v 0.6.1 2002/06/13 15:12:26 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
 
 /* system includes */
 #include <stdio.h>
+#include <stdlib.h>
 #include <stdint.h>
+#include <string.h>
+#include <arpa/inet.h>
 
 /* Prototypes defs */
 extern void print_buffer(int count, char *buff);
 extern char *ip_ntoa(uint32_t ip);
+extern uint32_t ip_ston(char *addr);
+extern uint8_t ip_stom(char *addr);
 
 #endif
index b141bfe..69bbcd4 100644 (file)
--- a/vector.c
+++ b/vector.c
@@ -5,7 +5,7 @@
  * 
  * Part:        Vector structure manipulation.
  *  
- * Version:     $Id: vector.c,v 0.5.9 2002/05/30 16:05:31 acassen Exp $
+ * Version:     $Id: vector.c,v 0.6.1 2002/06/13 15:12:26 acassen Exp $
  * 
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *              
@@ -49,6 +49,20 @@ void vector_free(vector v)
   FREE(v->slot);
   FREE(v);
 }
+void free_strvec(vector strvec)
+{
+  int i;
+  char *str;
+
+  if (!strvec)
+    return;
+
+  for (i=0; i < VECTOR_SIZE(strvec); i++)
+    if ((str = VECTOR_SLOT(strvec, i)) != NULL)
+      FREE(str);
+
+  vector_free(strvec);
+}
 
 /* Set a vector slot value */
 void vector_set_slot(vector v, void *value)
@@ -69,3 +83,20 @@ void vector_dump(vector v)
     if (v->slot[i] != NULL)
       printf("  Slot [%d]: %p\n", i, VECTOR_SLOT(v, i));
 }
+
+void dump_strvec(vector strvec)
+{
+  int i;
+  char *str;
+
+  if (!strvec)
+    return;
+
+  printf("String Vector : ");
+
+  for (i = 0; i < VECTOR_SIZE(strvec); i++) {
+    str = VECTOR_SLOT(strvec, i);
+    printf("[%i]=%s ", i, str);
+  }
+  printf("\n");
+}
index c717669..46256f8 100644 (file)
--- a/vector.h
+++ b/vector.h
@@ -5,7 +5,7 @@
  * 
  * Part:        vector.c include file.
  *  
- * Version:     $Id: vector.h,v 0.5.9 2002/05/30 16:05:31 acassen Exp $
+ * Version:     $Id: vector.h,v 0.6.1 2002/06/13 15:12:26 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
@@ -39,7 +39,9 @@ typedef struct _vector *vector;
 extern vector vector_alloc(void);
 extern void vector_alloc_slot(vector v);
 extern void vector_free(vector v);
+extern void free_strvec(vector strvec);
 extern void vector_set_slot(vector v, void *value);
 extern void vector_dump(vector v);
+extern void dump_strvec(vector strvec);
 
 #endif
diff --git a/vrrp.c b/vrrp.c
index dc7652e..b67e47e 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.9 2002/05/30 16:05:31 acassen Exp $
+ * Version:     $Id: vrrp.c,v 0.6.1 2002/06/13 15:12:26 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
@@ -181,7 +181,7 @@ static int vrrp_handle_ipaddress(vrrp_rt *vrrp, int cmd, int type)
     vip_addr *vadd = (type == VRRP_VIP_TYPE)?&vrrp->vaddr[i]:&vrrp->evaddr[i];
     if(!cmd && !vadd->set) continue;
 retry:
-    if (netlink_address_ipv4(ifindex , ntohl(vadd->addr), cmd) < 0) {
+    if (netlink_address_ipv4(ifindex , vadd->addr, vadd->mask, cmd) < 0) {
       err = 1;
       vadd->set = 0;
       syslog(LOG_INFO, "cant %s the address %s to %s\n"
@@ -190,7 +190,7 @@ retry:
                      , IF_NAME(vrrp->ifp));
       if (cmd == VRRP_IPADDRESS_ADD) {
         syslog(LOG_INFO, "try to delete eventual stalled ip");
-        netlink_address_ipv4(ifindex, ntohl(vadd->addr), VRRP_IPADDRESS_DEL);
+        netlink_address_ipv4(ifindex, vadd->addr, vadd->mask, VRRP_IPADDRESS_DEL);
         if (retry < 4) {
           retry++;
           goto retry;
@@ -461,7 +461,7 @@ static void vrrp_build_ip(vrrp_rt *vrrp, char *buffer, int buflen)
 
   /* fill protocol type --rfc2402.2 */
   ip->protocol = (vrrp->auth_type == VRRP_AUTH_AH)?IPPROTO_IPSEC_AH:IPPROTO_VRRP;
-  ip->saddr    = IF_ADDR(vrrp->ifp);
+  ip->saddr    = VRRP_PKT_SADDR(vrrp);
   ip->daddr    = htonl(INADDR_VRRP_GROUP);
 
   /* checksum must be done last */
@@ -729,9 +729,9 @@ static int send_gratuitous_arp(vrrp_rt *vrrp, int addr)
   arph->ar_pln = 4;
   arph->ar_op  = htons(ARPOP_REQUEST);
   memcpy(arph->__ar_sha, hwaddr, hwlen);
-  addr = htonl(addr);
   memcpy(arph->__ar_sip, &addr, sizeof(addr));
   memcpy(arph->__ar_tip, &addr, sizeof(addr));
+
   return vrrp_send_pkt(vrrp, buf, buflen);
 }
 
@@ -747,9 +747,9 @@ void vrrp_send_gratuitous_arp(vrrp_rt *vrrp)
 
   for (j = 0; j < 5; j++) {
     for (i = 0; i < vrrp->naddr; i++)
-      send_gratuitous_arp(vrrp, ntohl(vrrp->vaddr[i].addr));
+      send_gratuitous_arp(vrrp, vrrp->vaddr[i].addr);
     for (i = 0; i < vrrp->neaddr; i++)
-      send_gratuitous_arp(vrrp, ntohl(vrrp->evaddr[i].addr));
+      send_gratuitous_arp(vrrp, vrrp->evaddr[i].addr);
   }
 }
 
@@ -884,10 +884,7 @@ void vrrp_state_master_tx(vrrp_rt *vrrp, const int prio)
     vrrp_state_become_master(vrrp);
   }
 
-  if (prio == VRRP_PRIO_OWNER)
-    vrrp_send_adv(vrrp, VRRP_PRIO_OWNER);
-  else
-    vrrp_send_adv(vrrp, vrrp->priority);
+  vrrp_send_adv(vrrp, (prio==VRRP_PRIO_OWNER)?VRRP_PRIO_OWNER:vrrp->priority);
 }
 
 int vrrp_state_master_rx(vrrp_rt *vrrp, char *buf, int buflen)
@@ -936,7 +933,7 @@ int vrrp_state_master_rx(vrrp_rt *vrrp, char *buf, int buflen)
     return 0;
   } else if (hd->priority > vrrp->priority   ||
              (hd->priority == vrrp->priority &&
-             ntohl(iph->saddr) > IF_ADDR(vrrp->ifp))) {
+             ntohl(iph->saddr) > VRRP_PKT_SADDR(vrrp))) {
     syslog(LOG_INFO, "VRRP_Instance(%s) Received higher prio advert"
                    , vrrp->iname);
     vrrp->ms_down_timer = 3 * vrrp->adver_int + VRRP_TIMER_SKEW(vrrp);
diff --git a/vrrp.h b/vrrp.h
index 9ce0715..7c27405 100644 (file)
--- a/vrrp.h
+++ b/vrrp.h
@@ -6,10 +6,9 @@
  *
  * Part:        vrrp.c program include file.
  *
- * Version:     $Id: vrrp.h,v 0.5.9 2002/05/30 16:05:31 acassen Exp $
+ * Version:     $Id: vrrp.h,v 0.6.1 2002/06/13 15:12:26 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
- *              Based on the Jerome Etienne, <jetienne@arobas.net> code.
  *
  *              This program is distributed in the hope that it will be useful, 
  *              but WITHOUT ANY WARRANTY; without even the implied warranty of 
@@ -40,6 +39,7 @@
 #include "vrrp_if.h"
 #include "timer.h"
 #include "utils.h"
+#include "vector.h"
 
 typedef struct {       /* rfc2338.5.1 */
        uint8_t         vers_type;      /* 0-3=type, 4-7=version */
@@ -68,21 +68,34 @@ 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 vrrp sync group. A vrrp_sync_group is a set
+ * of VRRP instances that need to be state sync together.
+ */
+typedef struct _vrrp_sgroup {
+        char    *gname;         /* Group name */
+        vector  iname;          /* Set of VRRP instances in this group */
+        int     state;          /* current stable state */
+} vrrp_sgroup;
+
+
+/* parameters per virtual router -- rfc2338.6.1.2 */
 typedef struct {
        uint32_t        addr;   /* the ip address */
+       uint8_t         mask;   /* the ip address CIDR netmask */
        int             set;    /* TRUE if addr is set */
 } vip_addr;
 
-/* parameters per virtual router -- rfc2338.6.1.2 */
 typedef struct _vrrp_rt {
        char    *iname;         /* Instance Name */
-       char    *isync;         /* Instance Name to be sync with */
+       vrrp_sgroup *sync;
        interface *ifp;         /* Interface we belong to */
+       uint32_t  mcast_saddr;  /* Src IP address to use in VRRP IP header */
        char    *lvs_syncd_if;  /* handle LVS sync daemon state using this
                                  * instance FSM & running on specific interface
                                  * => eth0 for example.
                                  */
-
        int     vrid;           /* virtual id. from 1(!) to 255 */
        int     priority;       /* priority value */
        int     naddr;          /* number of ip addresses */
@@ -170,6 +183,8 @@ typedef struct _vrrp_rt {
 #define VRRP_MIN(a, b) ((a) < (b)?(a):(b))
 #define VRRP_MAX(a, b) ((a) > (b)?(a):(b))
 
+#define VRRP_PKT_SADDR(V) (((V)->mcast_saddr)?(V)->mcast_saddr:IF_ADDR((V)->ifp))
+
 /* prototypes */
 extern int open_vrrp_socket(const int proto, const int index);
 extern void new_vrrp_socket(vrrp_rt *vrrp);
index 78dcac0..6f2add2 100644 (file)
--- a/vrrp_if.c
+++ b/vrrp_if.c
@@ -5,7 +5,7 @@
  *
  * Part:        Interfaces manipulation.
  *
- * Version:     $Id: vrrp_if.c,v 0.5.9 2002/05/30 16:05:31 acassen Exp $
+ * Version:     $Id: vrrp_if.c,v 0.6.1 2002/06/13 15:12:26 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
@@ -24,6 +24,9 @@
 #include <unistd.h>
 #include <string.h>
 #include <sys/types.h>
+  typedef __uint32_t u32;
+  typedef __uint16_t u16;
+  typedef __uint8_t  u8;
 #include <sys/socket.h>
 #include <sys/ioctl.h>
 #include <netinet/ip.h>
@@ -37,6 +40,7 @@
 #endif
 #include <stdlib.h>
 #include <stdio.h>
+#include <linux/ethtool.h>
 
 /* local include */
 #include "scheduler.h"
@@ -167,6 +171,49 @@ int if_mii_probe(const char *ifname)
   return status;
 }
 
+static int if_ethtool_status(const int fd)
+{
+  struct ethtool_value edata;
+  int err = 0;
+
+  edata.cmd = ETHTOOL_GLINK;
+  ifr.ifr_data = (caddr_t)&edata;
+  err = ioctl(fd, SIOCETHTOOL, &ifr);
+  if (err == 0)
+    return (edata.data)?1:0;
+  else
+    return -1;
+}
+
+int if_ethtool_probe(const char *ifname)
+{
+  int fd = socket(AF_INET, SOCK_DGRAM, 0);
+  int status = 0;
+
+  if (fd < 0) return -1;
+  memset(&ifr, 0, sizeof(struct ifreq));
+  strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
+
+  status = if_ethtool_status(fd);
+  close(fd);
+  return status;
+}
+
+void if_ioctl_flags(interface *ifp)
+{
+  int fd = socket(AF_INET, SOCK_DGRAM, 0);
+
+  if (fd < 0) return;
+  memset(&ifr, 0, sizeof(struct ifreq));
+  strncpy(ifr.ifr_name, ifp->ifname, sizeof(ifr.ifr_name));
+  if (ioctl(fd, SIOCGIFFLAGS, &ifr) < 0) {
+    close (fd);
+    return;
+  }
+  ifp->flags = ifr.ifr_flags;
+  close(fd);
+}
+
 /* Interfaces lookup */
 static void free_if(void *data)
 {
@@ -210,9 +257,13 @@ void dump_if(void *data)
       break;
   }
 
-  /* MII registers supported ? */
+  /* MII channel supported ? */
   if (IF_MII_SUPPORTED(ifp))
     syslog(LOG_INFO, " NIC support MII regs");
+  else if (IF_ETHTOOL_SUPPORTED(ifp))
+    syslog(LOG_INFO, " NIC support EHTTOOL GLINK interface");
+  else
+    syslog(LOG_INFO, " Enabling NIC ioctl refresh polling");
 }
 
 static void init_if_queue(void)
@@ -232,36 +283,41 @@ static void init_if_mii(void)
 
   for (e = LIST_HEAD(if_queue); e; ELEMENT_NEXT(e)) {
     ifp = ELEMENT_DATA(e);
+    ifp->lb_type = LB_IOCTL;
     status = if_mii_probe(ifp->ifname);
-    if (status < 0)
-      ifp->mii = 0;
-    else {
-      ifp->mii = 1;
-      ifp->mii_linkbeat = (status)?1:0;
+    if (status >= 0) {
+      ifp->lb_type = LB_MII;
+      ifp->linkbeat = (status)?1:0;
+    } else {
+      status = if_ethtool_probe(ifp->ifname);
+      if (status >= 0) {
+        ifp->lb_type = LB_ETHTOOL;
+        ifp->linkbeat = (status)?1:0;
+      }
     }
   }
 }
 
-static void if_mii_refresh(void)
+static void if_linkbeat_refresh(void)
 {
   interface *ifp;
   element e;
 
   for (e = LIST_HEAD(if_queue); e; ELEMENT_NEXT(e)) {
     ifp = ELEMENT_DATA(e);
-    if (IF_MII_SUPPORTED(ifp)) {
-      if (IF_LINK_ISUP(ifp->ifname))
-        ifp->mii_linkbeat = 1;
-      else
-        ifp->mii_linkbeat = 0;
-    }
+    if (IF_MII_SUPPORTED(ifp))
+      ifp->linkbeat = (if_mii_probe(ifp->ifname))?1:0;
+    else if (IF_ETHTOOL_SUPPORTED(ifp))
+      ifp->linkbeat = (if_ethtool_probe(ifp->ifname))?1:0;
+    else
+      if_ioctl_flags(ifp);
   }
 }
 
-int if_mii_linkbeat(const interface *ifp)
+int if_linkbeat(const interface *ifp)
 {
-  if (IF_MII_SUPPORTED(ifp))
-    return IF_MII_LINKBEAT(ifp);
+  if (IF_MII_SUPPORTED(ifp) || IF_ETHTOOL_SUPPORTED(ifp))
+    return IF_LINKBEAT(ifp);
   return 1;
 }
 
@@ -269,7 +325,7 @@ int if_mii_linkbeat(const interface *ifp)
 int if_monitor_thread(thread *thread)
 {
   /* If present, refresh link beat status from MII BMSR */
-  if_mii_refresh();
+  if_linkbeat_refresh();
 
   /* Register new monitor thread */
   thread_add_timer(master, if_monitor_thread
@@ -290,10 +346,11 @@ void init_interface_queue(void)
   init_if_queue();
   netlink_interface_lookup();
   init_if_mii();
-//  dump_list(if_queue);
 }
 void if_mii_poller_init(void)
 {
+//  dump_list(if_queue);
+
   /* Register NIC Heartbeat monitoring thread */
   thread_add_timer(master, if_monitor_thread
                          , NULL
index dce3511..e25baec 100644 (file)
--- a/vrrp_if.h
+++ b/vrrp_if.h
@@ -5,7 +5,7 @@
  *
  * Part:        vrrp_if.c include file.
  *
- * Version:     $Id: vrrp_if.h,v 0.5.9 2002/05/30 16:05:31 acassen Exp $
+ * Version:     $Id: vrrp_if.h,v 0.6.1 2002/06/13 15:12:26 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
@@ -31,6 +31,9 @@
 #include "list.h"
 
 /* types definition */
+#ifndef SIOCETHTOOL
+  #define SIOCETHTOOL     0x8946
+#endif
 #ifndef SIOCGMIIPHY
   #define SIOCGMIIPHY (SIOCDEVPRIVATE)            /* Get the PHY in use. */
   #define SIOCGMIIREG (SIOCDEVPRIVATE+1)          /* Read a PHY register. */
 #define ARPHRD_LOOPBACK 772
 #define POLLING_DELAY 1
 
+/* Interface Linkbeat code selection */
+#define LB_IOCTL   0x1
+#define LB_MII     0x2
+#define LB_ETHTOOL 0x4
+
 /* Interface structure definition */
 typedef struct _interface {
   char ifname[IF_NAMESIZ + 1];         /* Interface name */
   unsigned int ifindex;                        /* Interface index */
   uint32_t address;                    /* Interface main primary IP address */
-//  list primary;
-//  list secondary;
   unsigned long flags;                 /* flags */
   unsigned int mtu;                    /* MTU for this interface */
   unsigned short hw_type;              /* Type of hardware address */
   u_char hw_addr[IF_HWADDR_MAX];       /* MAC address */
   int hw_addr_len;                     /* MAC addresss length */
-  int mii;                             /* Interface support MII regs ? */
-  int mii_linkbeat;                    /* LinkBeat from MII BMSR req */
+  int lb_type;                         /* Interface regs selection */
+  int linkbeat;                                /* LinkBeat from MII BMSR req */
 } interface;
 
 /* Global interface queue */
@@ -70,18 +76,19 @@ list if_queue;
 #define IF_INDEX(X) ((X)->ifindex)
 #define IF_ADDR(X) ((X)->address)
 #define IF_HWADDR(X) ((X)->hw_addr)
-#define IF_LINK_ISUP(X) (if_mii_probe(X))
-#define IF_MII_SUPPORTED(X) ((X)->mii)
-#define IF_MII_LINKBEAT(X) ((X)->mii_linkbeat)
+#define IF_MII_SUPPORTED(X) ((X)->lb_type & LB_MII)
+#define IF_ETHTOOL_SUPPORTED(X) ((X)->lb_type & LB_ETHTOOL)
+#define IF_LINKBEAT(X) ((X)->linkbeat)
 #define IF_ISUP(X) (((X)->flags & IFF_UP)      && \
                     ((X)->flags & IFF_RUNNING) && \
-                    if_mii_linkbeat(X))
+                    if_linkbeat(X))
 
 /* prototypes */
 extern interface *if_get_by_ifindex(const int ifindex);
 extern interface *if_get_by_ifname(const char *ifname);
-extern int if_mii_linkbeat(const interface *ifp);
+extern int if_linkbeat(const interface *ifp);
 extern int if_mii_probe(const char *ifname);
+extern int if_ethtool_probe(const char *ifname);
 extern void if_mii_poller_init(void);
 extern void if_add_queue(interface *ifp);
 extern int if_monitor_thread(thread *thread);
index 4ef3bd3..fcdc0e1 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Part:        NETLINK IPv4 address manipulation.
  *
- * Version:     $Id: vrrp_ipaddress.c,v 0.5.9 2002/05/30 16:05:31 acassen Exp $
+ * Version:     $Id: vrrp_ipaddress.c,v 0.6.1 2002/06/13 15:12:26 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
@@ -26,7 +26,7 @@
 #include "utils.h"
 
 /* Add/Delete IP address to a specific interface */
-int netlink_address_ipv4(int ifindex, uint32_t addr, int cmd)
+int netlink_address_ipv4(int ifindex, uint32_t addr, uint8_t mask, int cmd)
 {
   struct nl_handle nlh;
   int status = 1;
@@ -43,9 +43,7 @@ int netlink_address_ipv4(int ifindex, uint32_t addr, int cmd)
   req.n.nlmsg_type   = cmd ? RTM_NEWADDR:RTM_DELADDR;
   req.ifa.ifa_family = AF_INET;
   req.ifa.ifa_index  = ifindex;
-  req.ifa.ifa_prefixlen  = 32;
-
-  addr = htonl(addr);
+  req.ifa.ifa_prefixlen = mask;
   addattr_l(&req.n, sizeof(req), IFA_LOCAL, &addr, sizeof(addr));
 
   if (netlink_socket(&nlh, 0) < 0)
index d636127..4afd773 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Part:        vrrp_ipaddress.c include file.
  *
- * Version:     $Id: vrrp_ipaddress.h,v 0.5.9 2002/05/30 16:05:31 acassen Exp $
+ * Version:     $Id: vrrp_ipaddress.h,v 0.6.1 2002/06/13 15:12:26 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
@@ -35,7 +35,9 @@
 #define VRRP_IPADDRESS_ADD 1
 
 /* prototypes */
-extern int netlink_address_ipv4(int ifindex, uint32_t addr, int cmd);
+extern int netlink_address_ipv4(int ifindex, uint32_t addr
+                                           , uint8_t mask
+                                           , int cmd);
 
 #endif
 
index 2ef96a6..2f9aa18 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.9 2002/05/30 16:05:31 acassen Exp $
+ * Version:     $Id: vrrp_ipsecah.c,v 0.6.1 2002/06/13 15:12:26 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
index 2a3c9a7..f608cae 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Part:        vrrp_ipsecah.c include file.
  * 
- * Version:     $Id: vrrp_ipsecah.h,v 0.5.9 2002/05/30 16:05:31 acassen Exp $
+ * Version:     $Id: vrrp_ipsecah.h,v 0.6.1 2002/06/13 15:12:26 acassen Exp $
  * 
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *              
index 5151557..7a136ef 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Part:        NETLINK kernel command channel.
  *
- * Version:     $Id: vrrp_netlink.c,v 0.5.9 2002/05/30 16:05:31 acassen Exp $
+ * Version:     $Id: vrrp_netlink.c,v 0.6.1 2002/06/13 15:12:26 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
@@ -35,6 +35,7 @@
 #include <sys/uio.h>
 
 /* local include */
+#include "check_api.h"
 #include "vrrp_netlink.h"
 #include "vrrp_if.h"
 #include "memory.h"
@@ -351,6 +352,7 @@ static int netlink_if_address_filter(struct sockaddr_nl *snl, struct nlmsghdr *h
   struct ifaddrmsg *ifa;
   struct rtattr *tb[IFA_MAX + 1];
   interface *ifp;
+  uint32_t address = 0;
   int len;
 
   ifa = NLMSG_DATA(h);
@@ -375,28 +377,27 @@ static int netlink_if_address_filter(struct sockaddr_nl *snl, struct nlmsghdr *h
   if (!ifp)
     return 0;
 
-  if (ifa->ifa_flags & IFA_F_SECONDARY)
-    return 0;
-
   if (tb[IFA_ADDRESS] == NULL)
     tb[IFA_ADDRESS] = tb[IFA_LOCAL];
 
   if (ifp->flags & IFF_POINTOPOINT) {
-    if (tb[IFA_LOCAL]) {
-      ifp->address = *(uint32_t *)RTA_DATA(tb[IFA_LOCAL]);
-    } else {
-      if (tb[IFA_ADDRESS])
-        ifp->address = *(uint32_t *)RTA_DATA(tb[IFA_LOCAL]);
-    }
+    if (tb[IFA_LOCAL])
+      address = *(uint32_t *)RTA_DATA(tb[IFA_LOCAL]);
   } else {
     if (tb[IFA_ADDRESS])
-      ifp->address = *(uint32_t *)RTA_DATA(tb[IFA_ADDRESS]);
+      address = *(uint32_t *)RTA_DATA(tb[IFA_ADDRESS]);
   }
 
+  /* If no address is set on interface then set the first time */
+  if (!ifp->address)
+    ifp->address = address;
+
+  /* Refresh checkers state */
+  update_checker_activity(address, (h->nlmsg_type == RTM_NEWADDR)?1:0);
   return 0;
 }
 
-/* Interface lookup bootstrap function */
+/* Interfaces lookup bootstrap function */
 int netlink_interface_lookup(void)
 {
   struct nl_handle nlh;
@@ -408,18 +409,32 @@ int netlink_interface_lookup(void)
   /* Interface lookup */
   if (netlink_request(&nlh, AF_PACKET, RTM_GETLINK) < 0) {
     status = -1;
-    goto end;
+    goto end_int;
   }
   status = netlink_parse_info(netlink_if_link_filter, &nlh); 
 
+end_int:
+  netlink_close(&nlh);
+  return status;
+}
+
+/* Adresses lookup bootstrap function */
+static int netlink_address_lookup(void)
+{
+  struct nl_handle nlh;
+  int status = 0;
+
+  if (netlink_socket(&nlh, 0) < 0)
+    return -1;
+
   /* Address lookup */
   if (netlink_request(&nlh, AF_INET, RTM_GETADDR) < 0) {
     status = -1;
-    goto end;
+    goto end_addr;
   }
   status = netlink_parse_info(netlink_if_address_filter, &nlh); 
-  
-end:
+
+end_addr:
   netlink_close(&nlh);
   return status;
 }
@@ -471,7 +486,7 @@ static int netlink_broadcast_filter(struct sockaddr_nl *snl, struct nlmsghdr *h)
       break;
     case RTM_NEWADDR:
     case RTM_DELADDR:
-//      return netlink_if_address_filter(snl, h);
+      return netlink_if_address_filter(snl, h);
       break;
     default:
       syslog(LOG_INFO, "Kernel is reflecting an unknown netlink nlmsg_type: %d"
@@ -498,6 +513,14 @@ void kernel_netlink_init(void)
 {
   unsigned long groups;
 
+  /* Start with a netlink address lookup */
+  netlink_address_lookup();
+
+  /*
+   * Prepare netlink kernel broadcast channel
+   * subscribtion. We subscribe to LINK and ADDR
+   * netlink broadcast messages.
+   */
   groups = RTMGRP_LINK | RTMGRP_IPV4_IFADDR;
   netlink_socket(&nl_kernel, groups);
 
index d456f22..152136e 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Part:        vrrp_netlink.c include file.
  *
- * Version:     $Id: vrrp_netlink.h,v 0.5.9 2002/05/30 16:05:31 acassen Exp $
+ * Version:     $Id: vrrp_netlink.h,v 0.6.1 2002/06/13 15:12:26 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
index 0afbbaf..a3409a6 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Part:        Sheduling framework for vrrp code.
  *
- * Version:     $Id: vrrp_scheduler.c,v 0.5.9 2002/05/30 16:05:31 acassen Exp $
+ * Version:     $Id: vrrp_scheduler.c,v 0.6.1 2002/06/13 15:12:26 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
@@ -22,9 +22,9 @@
 
 #include "vrrp_scheduler.h"
 #include "vrrp_ipsecah.h"
-#include "vrrp_netlink.h"
 #include "vrrp_if.h"
 #include "vrrp.h"
+#include "vrrp_sync.h"
 #include "ipvswrapper.h"
 #include "memory.h"
 #include "list.h"
@@ -369,20 +369,6 @@ int vrrp_dispatcher_init(thread *thread)
   return 1;
 }
 
-static vrrp_rt *vrrp_search_instance_isync(char *isync)
-{
-  vrrp_rt *vrrp;
-  list l = conf_data->vrrp;
-  element e;
-
-  for (e = LIST_HEAD(l); e; ELEMENT_NEXT(e)) {
-    vrrp = ELEMENT_DATA(e);
-    if (strcmp(vrrp->iname, isync) == 0)
-      return vrrp;
-  }
-  return NULL;
-}
-
 static vrrp_rt *vrrp_search_instance(const int vrid)
 {
   vrrp_rt *vrrp;
@@ -459,15 +445,9 @@ static void vrrp_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))) {
+    if (vrrp->sync) {
+      if (vrrp_sync_leave_fault(vrrp)) {
         syslog(LOG_INFO, "VRRP_Instance(%s) prio is higher than received advert"
                        , vrrp->iname);
         vrrp_become_master(vrrp, vrrp_buffer, len);
@@ -486,6 +466,7 @@ static void vrrp_leave_dummy_master(vrrp_rt *vrrp
                                            , char *vrrp_buffer
                                            , int len)
 {
+/*
   vrrp_rt *vrrp_isync;
 
   if (vrrp->isync) {
@@ -510,6 +491,7 @@ static void vrrp_leave_dummy_master(vrrp_rt *vrrp
       }
     }
   }
+*/
 }
 
 static void vrrp_goto_master(vrrp_rt *vrrp)
@@ -623,7 +605,6 @@ static void vrrp_dummy_master(vrrp_rt *vrrp)
 static int vrrp_dispatcher_read_to(int fd)
 {
   vrrp_rt *vrrp;
-  vrrp_rt *vrrp_isync;
   int vrid = 0;
   int prev_state = 0;
 
@@ -631,75 +612,12 @@ static int vrrp_dispatcher_read_to(int fd)
   vrid = vrrp_timer_vrid_timeout(fd);
   vrrp = vrrp_search_instance(vrid);
 
+  /* Run the FSM handler */
   prev_state = vrrp->state;
   VRRP_FSM_READ_TO(vrrp);
 
-  /* handle master instance synchronization */
-  if (prev_state  == VRRP_STATE_BACK && 
-      vrrp->state == VRRP_STATE_MAST &&
-      vrrp->isync) {
-    vrrp_isync = vrrp_search_instance_isync(vrrp->isync);
-
-    if (vrrp_isync->state == VRRP_STATE_BACK) {
-      syslog(LOG_INFO, "VRRP_Instance(%s) must be sync with %s"
-                      , vrrp->iname
-                      , vrrp_isync->iname);
-
-      /* Send the higher priority advert */
-      syslog(LOG_INFO, "VRRP_Instance(%s) sending OWNER advert"
-                     , vrrp_isync->iname);
-      vrrp_state_master_tx(vrrp_isync, VRRP_PRIO_OWNER);
-    } else {
-      /* Otherwise, we simply update remotes arp caches */
-      vrrp_isync->state = VRRP_STATE_MAST;
-      vrrp_send_gratuitous_arp(vrrp_isync);
-    }
-  }
-
-  /* handle synchronization in FAULT state */
-  if (prev_state  == VRRP_STATE_MAST  &&
-      vrrp->state == VRRP_STATE_FAULT && 
-      vrrp->isync) {
-    vrrp_isync = vrrp_search_instance_isync(vrrp->isync);
-
-    if (vrrp_isync->state == VRRP_STATE_MAST) {
-      /*
-       * We force sync instance to backup mode.
-       * This reduce instance takeover to less than ms_down_timer.
-       * => by default ms_down_timer is set to 3secs.
-       * => Takeover will be less than 3secs !
-       */
-      //vrrp_isync->wantstate = VRRP_STATE_BACK;
-      vrrp_isync->wantstate = VRRP_STATE_GOTO_FAULT;
-    }
-  }
-
-  /*
-   * Break a MASTER/BACKUP state loop after sync instance
-   * FAULT state transition.
-   * => We doesn't receive remote MASTER adverts.
-   * => Emulate a DUMMY master to break the loop.
-   */
-  if (prev_state  == VRRP_STATE_MAST &&
-      vrrp->state == VRRP_STATE_BACK && 
-      vrrp->isync) {
-    vrrp_isync = vrrp_search_instance_isync(vrrp->isync);
-
-    if (vrrp_isync->state == VRRP_STATE_FAULT) {
-      syslog(LOG_INFO, "VRRP_Instance(%s) Transition to DUMMY MASTER"
-                     , vrrp->iname);
-      vrrp->wantstate = VRRP_STATE_GOTO_DUMMY_MAST;
-    }
-  }
-
-  /* previous state symetry */
-  if (vrrp->state == VRRP_STATE_DUMMY_MAST &&
-      vrrp->isync) {
-    vrrp_isync = vrrp_search_instance_isync(vrrp->isync);
-
-    if (vrrp_isync->state == VRRP_STATE_MAST)
-      vrrp->state = VRRP_STATE_MAST;
-  }
+  /* handle instance synchronization */
+  vrrp_sync_read_to(vrrp, prev_state);
 
   /*
    * We are sure the instance exist. So we can
@@ -713,7 +631,6 @@ static int vrrp_dispatcher_read_to(int fd)
 static int vrrp_dispatcher_read(int fd)
 {
   vrrp_rt *vrrp;
-  vrrp_rt *vrrp_isync;
   char *vrrp_buffer;
   struct iphdr *iph;
   vrrp_pkt *hd;
@@ -742,43 +659,12 @@ static int vrrp_dispatcher_read(int fd)
     return fd;
   }
 
+  /* Run the FSM handler */
   prev_state = vrrp->state;
   VRRP_FSM_READ(vrrp, vrrp_buffer, len);
 
-  /* handle backup instance synchronization */
-  if (prev_state  == VRRP_STATE_MAST && 
-      vrrp->state == VRRP_STATE_BACK &&
-      vrrp->isync) {
-    vrrp_isync = vrrp_search_instance_isync(vrrp->isync);
-
-    if (vrrp_isync->state == VRRP_STATE_MAST) {
-      syslog(LOG_INFO, "VRRP_Instance(%s) must be sync with %s"
-                     , vrrp->iname
-                     , vrrp_isync->iname);
-
-      /* Transition to BACKUP state */
-      vrrp_isync->wantstate = VRRP_STATE_BACK;
-    }
-  }
-
-  /*
-   * Handle wanted transition to MASTER state.
-   * When Instance not in FAULT state received a remote
-   * lower priotity advert => For a new VRRP election.
-   */
-  if (vrrp->state     == VRRP_STATE_BACK        && 
-      vrrp->wantstate == VRRP_STATE_GOTO_MASTER &&
-      vrrp->isync) {
-    vrrp_isync = vrrp_search_instance_isync(vrrp->isync);
-
-    if (vrrp_isync->state != VRRP_STATE_FAULT) {
-      /* Force a new protocol master election */
-      syslog(LOG_INFO, "VRRP_Instance(%s) forcing a new MASTER election"
-                     , vrrp->iname);
-      vrrp_send_adv(vrrp, vrrp->priority);
-    }
-  }
-
+  /* handle instance synchronization */
+  vrrp_sync_read(vrrp, prev_state);
 
   /*
    * Refresh sands only if found matching instance.
@@ -788,7 +674,6 @@ static int vrrp_dispatcher_read(int fd)
 
   /* cleanup the room */
   FREE(vrrp_buffer);
-
   return fd;
 }
 
index 1bacc8c..765bfcb 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Part:        vrrp_scheduler.c include file.
  * 
- * Version:     $Id: vrrp_scheduler.h,v 0.5.9 2002/05/30 16:05:31 acassen Exp $
+ * Version:     $Id: vrrp_scheduler.h,v 0.6.1 2002/06/13 15:12:26 acassen Exp $
  * 
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *              
@@ -30,9 +30,8 @@
 #include <string.h>
 #include <stdint.h>
 
-/* local include */
+/* local includes */
 #include "scheduler.h"
-#include "vrrp.h"
 
 /*
  * Our instance dispatcher use a socket pool.
diff --git a/vrrp_sync.c b/vrrp_sync.c
new file mode 100644 (file)
index 0000000..83c9d9f
--- /dev/null
@@ -0,0 +1,250 @@
+/*
+ * Soft:        Keepalived is a failover program for the LVS project
+ *              <www.linuxvirtualserver.org>. It monitor & manipulate
+ *              a loadbalanced server pool using multi-layer checks.
+ *
+ * Part:        VRRP synchronization framework.
+ *
+ * Version:     $Id: vrrp_sync.c,v 0.6.1 2002/06/13 15:12:26 acassen Exp $
+ *
+ * Author:      Alexandre Cassen, <acassen@linux-vs.org>
+ *
+ *              This program is distributed in the hope that it will be useful,
+ *              but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *              MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *              See the GNU General Public License for more details.
+ *
+ *              This program is free software; you can redistribute it and/or
+ *              modify it under the terms of the GNU General Public License
+ *              as published by the Free Software Foundation; either version
+ *              2 of the License, or (at your option) any later version.
+ */
+
+#include "vrrp_sync.h"
+#include "vrrp_if.h"
+#include "data.h"
+
+/* extern global vars */
+extern data *conf_data;
+
+/* return the first group found for a specific instance */
+vrrp_sgroup *vrrp_get_sync_group(char *iname)
+{
+  int i;
+  char *str;
+  element e;
+  vrrp_sgroup *vgroup;
+  list l = conf_data->vrrp_sync_group;
+
+  for (e = LIST_HEAD(l); e; ELEMENT_NEXT(e)) {
+    vgroup = ELEMENT_DATA(e);
+    for (i = 0; i < VECTOR_SIZE(vgroup->iname); i++) {
+      str = VECTOR_SLOT(vgroup->iname, i);
+      if (strcmp(str, iname) == 0)
+        return vgroup;
+    }
+  }
+  return NULL;
+}
+
+/* jointure between instance and group => iname */
+vrrp_rt *vrrp_get_instance(char *iname)
+{
+  vrrp_rt *vrrp;
+  list l = conf_data->vrrp;
+  element e;
+
+  for (e = LIST_HEAD(l); e; ELEMENT_NEXT(e)) {
+    vrrp = ELEMENT_DATA(e);
+    if (strcmp(vrrp->iname, iname) == 0)
+      return vrrp;
+  }
+  return NULL;
+}
+
+/* Leaving fault state */
+int vrrp_sync_leave_fault(vrrp_rt *vrrp)
+{
+  int i;
+  int not_fault = 0;
+  int is_up = 0;
+  char *str;
+  vrrp_rt *isync;
+  vrrp_sgroup *vgroup = vrrp->sync;
+
+  for (i = 0; i < VECTOR_SIZE(vgroup->iname); i++) {
+    str = VECTOR_SLOT(vgroup->iname, i);
+    isync = vrrp_get_instance(str);
+    if (IF_ISUP(isync->ifp))
+      is_up++;
+    if (isync != vrrp) {
+      if (isync->state != VRRP_STATE_FAULT)
+        not_fault++;
+    }
+  }
+
+  if (not_fault > 0 || is_up == VECTOR_SIZE(vgroup->iname)) {
+    syslog(LOG_INFO, "VRRP_Group(%s) Leaving FAULT state"
+                   , GROUP_NAME(vrrp->sync));
+    vgroup->state = VRRP_STATE_MAST;
+    return 1;
+  }
+  return 0;
+}
+
+static void vrrp_sync_backup(vrrp_rt *vrrp)
+{
+  int i;
+  char *str;
+  vrrp_rt *isync;
+  vrrp_sgroup *vgroup = vrrp->sync;
+
+  syslog(LOG_INFO, "VRRP_Group(%s) Syncing instances to BACKUP state"
+                 , GROUP_NAME(vrrp->sync));
+
+  for (i = 0; i < VECTOR_SIZE(vgroup->iname); i++) {
+    str = VECTOR_SLOT(vgroup->iname, i);
+    isync = vrrp_get_instance(str);
+    if (isync != vrrp)
+      isync->wantstate = VRRP_STATE_BACK;
+  }
+  vgroup->state = VRRP_STATE_BACK;
+}
+
+static void vrrp_sync_master_to(vrrp_rt *vrrp)
+{
+  int i;
+  char *str;
+  vrrp_rt *isync;
+  vrrp_sgroup *vgroup = vrrp->sync;
+
+  syslog(LOG_INFO, "VRRP_Group(%s) Syncing instances to MASTER state"
+                 , GROUP_NAME(vrrp->sync));
+
+  for (i = 0; i < VECTOR_SIZE(vgroup->iname); i++) {
+    str = VECTOR_SLOT(vgroup->iname, i);
+    isync = vrrp_get_instance(str);
+
+    /* Send the higher priority advert on all synced instances */
+    if (isync != vrrp) {
+      syslog(LOG_INFO, "VRRP_Instance(%s) sending OWNER advert"
+                     , isync->iname);
+      vrrp_state_master_tx(isync, VRRP_PRIO_OWNER);
+      isync->state = VRRP_STATE_MAST;
+    }
+  }
+  vgroup->state = VRRP_STATE_MAST;
+}
+
+static void vrrp_sync_fault_to(vrrp_rt *vrrp)
+{
+  int i;
+  char *str;
+  vrrp_rt *isync;
+  vrrp_sgroup *vgroup = vrrp->sync;
+
+  syslog(LOG_INFO, "VRRP_Group(%s) Syncing instances to FAULT state"
+                 , GROUP_NAME(vrrp->sync));
+
+  for (i = 0; i < VECTOR_SIZE(vgroup->iname); i++) {
+    str = VECTOR_SLOT(vgroup->iname, i);
+    isync = vrrp_get_instance(str);
+
+    /*
+     * We force sync instance to backup mode.
+     * This reduce instance takeover to less than ms_down_timer.
+     * => by default ms_down_timer is set to 3secs.
+     * => Takeover will be less than 3secs !
+     */
+    if (isync != vrrp)
+      if (isync->state == VRRP_STATE_MAST)
+        isync->wantstate = VRRP_STATE_GOTO_FAULT;
+  }
+  vgroup->state = VRRP_STATE_FAULT;
+}
+
+static void vrrp_sync_dmaster_to(vrrp_rt *vrrp)
+{
+  int i;
+  char *str;
+  vrrp_rt *isync;
+  vrrp_sgroup *vgroup = vrrp->sync;
+
+  for (i = 0; i < VECTOR_SIZE(vgroup->iname); i++) {
+    str = VECTOR_SLOT(vgroup->iname, i);
+    isync = vrrp_get_instance(str);
+    if (isync != vrrp) {
+      if (isync->state == VRRP_STATE_FAULT) {
+        syslog(LOG_INFO, "VRRP_Instance(%s) Transition to DUMMY MASTER"
+                       , isync->iname);
+        isync->wantstate = VRRP_STATE_GOTO_DUMMY_MAST;
+      }
+    }
+  }
+  vgroup->state = VRRP_STATE_DUMMY_MAST;
+}
+
+/* Read TimeOut synchronization handler */
+void vrrp_sync_read_to(vrrp_rt *vrrp, int prev_state)
+{
+  /* Nothing to sync */
+  if (!vrrp->sync)
+    return;
+
+  /* Sync the group instance to MASTER state */
+  if (prev_state  == VRRP_STATE_BACK &&
+      vrrp->state == VRRP_STATE_MAST)
+    if (GROUP_STATE(vrrp->sync)  == VRRP_STATE_BACK)
+      vrrp_sync_master_to(vrrp);
+
+  /* sync the group instance to FAULT state */
+  if (prev_state  == VRRP_STATE_MAST &&
+      vrrp->state == VRRP_STATE_FAULT)
+    if (GROUP_STATE(vrrp->sync) == VRRP_STATE_MAST)
+      vrrp_sync_fault_to(vrrp);
+
+  /*
+   * Break a MASTER/BACKUP state loop after sync instance
+   * FAULT state transition.
+   * => We doesn't receive remote MASTER adverts.
+   * => Emulate a DUMMY master to break the loop.
+   */
+  if (prev_state  == VRRP_STATE_MAST &&
+      vrrp->state == VRRP_STATE_BACK)
+    if (GROUP_STATE(vrrp->sync) == VRRP_STATE_FAULT)
+      vrrp_sync_dmaster_to(vrrp);
+
+  /* previous state symetry */
+  if (vrrp->state == VRRP_STATE_DUMMY_MAST)
+    if (GROUP_STATE(vrrp->sync) == VRRP_STATE_MAST)
+      vrrp->state = VRRP_STATE_MAST;
+}
+
+/* Read TimeOut synchronization handler */
+void vrrp_sync_read(vrrp_rt *vrrp, int prev_state)
+{
+  /* Nothing to sync */
+  if (!vrrp->sync)
+    return;
+
+  /* sync the group instance to BACKUP state */
+  if (prev_state  == VRRP_STATE_MAST &&
+      vrrp->state == VRRP_STATE_BACK)
+    if (GROUP_STATE(vrrp->sync) == VRRP_STATE_MAST)
+      vrrp_sync_backup(vrrp);
+
+  /* 
+   * Handle wanted transition to MASTER state.
+   * When Instance not in FAULT state, we received a remote
+   * lower priotity advert => Force a new VRRP election.
+   */ 
+  if (vrrp->state     == VRRP_STATE_BACK &&
+      vrrp->wantstate == VRRP_STATE_GOTO_MASTER) {
+    if (GROUP_STATE(vrrp->sync) != VRRP_STATE_FAULT) {
+      /* Force a new protocol master election */
+      syslog(LOG_INFO, "VRRP_Instance(%s) forcing a new MASTER election"
+                     , vrrp->iname);
+      vrrp_send_adv(vrrp, vrrp->priority);
+    }
+  }
+}
diff --git a/vrrp_sync.h b/vrrp_sync.h
new file mode 100644 (file)
index 0000000..b7cb7eb
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * Soft:        Keepalived is a failover program for the LVS project
+ *              <www.linuxvirtualserver.org>. It monitor & manipulate
+ *              a loadbalanced server pool using multi-layer checks.
+ *
+ * Part:        vrrp_sync.c include file.
+ * 
+ * Version:     $Id: vrrp_sync.h,v 0.6.1 2002/06/13 15:12:26 acassen Exp $
+ * 
+ * Author:      Alexandre Cassen, <acassen@linux-vs.org>
+ *              
+ *              This program is distributed in the hope that it will be useful,
+ *              but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *              MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *              See the GNU General Public License for more details.
+ *              
+ *              This program is free software; you can redistribute it and/or
+ *              modify it under the terms of the GNU General Public License
+ *              as published by the Free Software Foundation; either version
+ *              2 of the License, or (at your option) any later version.
+ */
+
+#ifndef _VRRP_SYNC_H
+#define _VRRP_SYNC_H
+
+/* system include */
+#include <stdlib.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <string.h>
+#include <stdint.h>
+
+/* local include */
+#include "vrrp.h"
+
+
+/* MACRO definition */
+#define GROUP_STATE(G) ((G)->state)
+#define GROUP_NAME(G)  ((G)->gname)
+
+/* extern prototypes */
+extern vrrp_sgroup *vrrp_get_sync_group(char *iname);
+extern int vrrp_sync_leave_fault(vrrp_rt *vrrp);
+extern void vrrp_sync_read_to(vrrp_rt *vrrp, int prev_state);
+extern void vrrp_sync_read(vrrp_rt *vrrp, int prev_state);
+
+#endif