keepalived-1.0.2 v1.0.2
authorAlexandre Cassen <acassen@freebox.fr>
Sun, 13 Apr 2003 23:30:35 +0000 (01:30 +0200)
committerAlexandre Cassen <acassen@freebox.fr>
Mon, 28 Sep 2009 08:58:57 +0000 (10:58 +0200)
* keepalived-1.0.2 released.
* This release has been sponsorized by :
  edNET, <www.ednet.co.uk>
  Please visit sponsor homepage and thanks to them for supporting
  keepalived project.
* Added support to virtual_server_group so that a virtual_server
  can be either an IP:PORT, a fwmark or group. A group is a set
  of virtual_server IP:PORT, IP range and fwmark. So, now a
  real_server can be part of multiple virtual_server without launching
  multiple time the same healthchecker that finaly flood real_server.
  This extension is useful for big ISP/ASP configuration using many
  virtual_server.
  look at doc/samples/keepalived.conf.virtual_server_group.
* Extended differential configuration parser to support diff
  virtual_server_group entries keeping current entry state as
  persistent (weight, conn, ...) big work here...
* Added support to IP range declaration for virtual_server_group.
  The IP range has the notation XXX.YYY.ZZZ.WWW-VVV. This will
  set IPVS virtual_server from WWW to VVV monotonaly incremented by
  one.
  look at doc/samples/keepalived.conf.virtual_server_group.
* Dominik Vogt, <dominik.vogt@gmx.de> enhanced SIGCHLD handler to
  reap all zombie child processes.
* Created a generic allocation value block with callback handler for
  block parsing. This remove duplicated code in parser.
* VRRP : Jan Holmberg, <jan@artech.net> extended the virtual_routes
  and static_routes to support source route selection (netlink
  RTA_PREFSRC).
  look at doc/samples/keepalived.conf.routes.
* Some cosmetics patches to reduce code duplication.

74 files changed:
ChangeLog
VERSION
doc/keepalived.conf.SYNOPSIS
doc/samples/keepalived.conf.routes
doc/samples/keepalived.conf.virtual_server_group [new file with mode: 0644]
keepalived.spec
keepalived/core/daemon.c
keepalived/core/data.c
keepalived/core/layer4.c
keepalived/core/main.c
keepalived/core/parser.c
keepalived/core/pidfile.c
keepalived/core/smtp.c
keepalived/healthcheck/check_api.c
keepalived/healthcheck/check_ci.c
keepalived/healthcheck/check_http.c
keepalived/healthcheck/check_misc.c
keepalived/healthcheck/check_ssl.c
keepalived/healthcheck/check_tcp.c
keepalived/healthcheck/ipfwwrapper.c
keepalived/healthcheck/ipvswrapper.c
keepalived/healthcheck/ipwrapper.c
keepalived/include/check_api.h
keepalived/include/check_ci.h
keepalived/include/check_http.h
keepalived/include/check_misc.h
keepalived/include/check_ssl.h
keepalived/include/check_tcp.h
keepalived/include/daemon.h
keepalived/include/data.h
keepalived/include/ipfwwrapper.h
keepalived/include/ipvswrapper.h
keepalived/include/ipwrapper.h
keepalived/include/layer4.h
keepalived/include/main.h
keepalived/include/parser.h
keepalived/include/pidfile.h
keepalived/include/smtp.h
keepalived/include/vrrp.h
keepalived/include/vrrp_arp.h
keepalived/include/vrrp_if.h
keepalived/include/vrrp_ipaddress.h
keepalived/include/vrrp_iproute.h
keepalived/include/vrrp_ipsecah.h
keepalived/include/vrrp_netlink.h
keepalived/include/vrrp_notify.h
keepalived/include/vrrp_scheduler.h
keepalived/include/vrrp_sync.h
keepalived/vrrp/vrrp.c
keepalived/vrrp/vrrp_arp.c
keepalived/vrrp/vrrp_if.c
keepalived/vrrp/vrrp_ipaddress.c
keepalived/vrrp/vrrp_iproute.c
keepalived/vrrp/vrrp_ipsecah.c
keepalived/vrrp/vrrp_netlink.c
keepalived/vrrp/vrrp_notify.c
keepalived/vrrp/vrrp_scheduler.c
keepalived/vrrp/vrrp_sync.c
lib/html.c
lib/html.h
lib/list.c
lib/list.h
lib/memory.c
lib/memory.h
lib/notify.c
lib/notify.h
lib/scheduler.c
lib/scheduler.h
lib/timer.c
lib/timer.h
lib/utils.c
lib/utils.h
lib/vector.c
lib/vector.h

index 6322915..e382fc5 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,4 +1,36 @@
-2003-03-17  Alexandre Cassen  <acassen@linux-vs.org>
+2003-04-14  Alexandre Cassen  <acassen@linux-vs.org>
+       * keepalived-1.0.2 released.
+       * This release has been sponsorized by :
+         edNET, <www.ednet.co.uk>
+         Please visit sponsor homepage and thanks to them for supporting
+         keepalived project.
+       * Added support to virtual_server_group so that a virtual_server
+         can be either an IP:PORT, a fwmark or group. A group is a set
+         of virtual_server IP:PORT, IP range and fwmark. So, now a
+         real_server can be part of multiple virtual_server without launching
+         multiple time the same healthchecker that finaly flood real_server.
+         This extension is useful for big ISP/ASP configuration using many
+         virtual_server.
+         look at doc/samples/keepalived.conf.virtual_server_group.
+       * Extended differential configuration parser to support diff
+         virtual_server_group entries keeping current entry state as
+         persistent (weight, conn, ...) big work here...
+       * Added support to IP range declaration for virtual_server_group.
+         The IP range has the notation XXX.YYY.ZZZ.WWW-VVV. This will
+         set IPVS virtual_server from WWW to VVV monotonaly incremented by
+         one.
+         look at doc/samples/keepalived.conf.virtual_server_group.
+       * Dominik Vogt, <dominik.vogt@gmx.de> enhanced SIGCHLD handler to
+         reap all zombie child processes.
+       * Created a generic allocation value block with callback handler for
+         block parsing. This remove duplicated code in parser.
+       * VRRP : Jan Holmberg, <jan@artech.net> extended the virtual_routes
+         and static_routes to support source route selection (netlink
+         RTA_PREFSRC).
+         look at doc/samples/keepalived.conf.routes.
+       * Some cosmetics patches to reduce code duplication.
+
+003-03-17  Alexandre Cassen  <acassen@linux-vs.org>
        * keepalived-1.0.1 released.
        * This release has been sponsorized by :
          Creative Internet Techniques, <www.httpd.net>
diff --git a/VERSION b/VERSION
index 7dea76e..6d7de6e 100644 (file)
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-1.0.1
+1.0.2
index 91c3c61..09d57bd 100644 (file)
@@ -39,8 +39,8 @@ global_defs {                         # Block identification
        The configuration block looks like :
 
 static_routes {                                                        # block identification
-    [to] <IP ADDRESS>/<MASK> via|gw <IP ADDRESS> dev <STRING>  # to is optional
-    [to] <IP ADDRESS>/<MASK> via|gw <IP ADDRESS> dev <STRING>  # to is optional
+    src <IP ADDRESS> [to] <IP ADDRESS>/<MASK> via|gw <IP ADDRESS> dev <STRING> # to is optional
+    src <IP ADDRESS> [to] <IP ADDRESS>/<MASK> via|gw <IP ADDRESS> dev <STRING> # to is optional
     ...
 }
 
@@ -97,8 +97,8 @@ vrrp_instance <STRING> {              # VRRP instance declaration
         ...
     }
     virtual_routes {                    # VRRP virtual routes
-        [to] <IP ADDRESS>/<MASK> via|gw <IP ADDRESS> dev <STRING>      # to is optional
-        [to] <IP ADDRESS>/<MASK> via|gw <IP ADDRESS> dev <STRING>      # to is optional
+        src <IP ADDRESS> [to] <IP ADDRESS>/<MASK> via|gw <IP ADDRESS> dev <STRING>     # to is optional
+        src <IP ADDRESS> [to] <IP ADDRESS>/<MASK> via|gw <IP ADDRESS> dev <STRING>     # to is optional
         ...
     }
     preempt                            # VRRP preempt mode (default set)
@@ -112,9 +112,43 @@ vrrp_instance <STRING> {           # VRRP instance declaration
 
 3. LVS configuration
 
-The configuration block looks like :
+This block is divided in 2 sub-block :
+
+       * Virtual server group
+       * Virtual server
+
+       3.1. Virtual server group
+       
+       The configuration block looks like :
+
+virtual_server_group <STRING> {
+       <IP ADDRESS> <PORT>             # VIP VPORT
+       <IP ADDRESS> <PORT>
+       ...
+       <IP ADDRESS RANGE> <PORT>       # VIP range VPORT
+       <IP ADDRESS RANGE> <PORT>
+       ...
+       fwmark <INTEGER>                # fwmark
+       fwmark <INTEGER>
+       ...
+}
+
+Note:  <IP ADDRESS RANGE> has the form of : XXX.YYY.ZZZ.WWW-VVV, define
+       the IP address range starting at WWW and monotonaly incremented by
+       one to VVV. Example : 192.168.200.1-10 means .1 to .10 IP addresses.
+
+       3.2. Virtual server
+       
+       The configuration block looks like :
+
+       A virtual_server can be either :
+       * vip vport declaration
+       * fwmark declaration
+       * group declaration
 
-virtual_server <IP ADDRESS> <PORT> {   # VS declaration
+virtual_server <IP ADDRESS> <PORT> {   # VS IP/PORT declaration
+virtual_server fwmark <INTEGER>    {   # VS fwmark declaration
+virtual_server group <STRING>      {   # VS group declaration
     delay_loop <INTEGER>               # delay timer for service polling
     lb_algo rr|wrr|lc|wlc|lblc|sh|dh   # LVS scheduler used
     lb_kind NAT|DR|TUN                 # LVS method used
index ee7bd25..971bae1 100644 (file)
@@ -5,6 +5,7 @@ global_defs {
 }
 
 static_route {
+    src 192.168.100.1 192.168.209.0/24 via 192.168.200.254 dev eth0
     192.168.210.0/24 via 192.168.200.254 dev eth0
     192.168.211.0/24 via 192.168.200.254 dev eth0
     192.168.212.0/24 dev eth3
@@ -22,6 +23,7 @@ vrrp_instance VI_1 {
         192.168.200.18 dev eth2
     }
     virtual_routes {
+        src 192.168.100.1 192.168.109.0/24 via 192.168.200.254 dev eth1
         192.168.110.0/24 via 192.168.200.254 dev eth1
         192.168.111.0/24 dev eth2
         192.168.112.0/24 via 192.168.100.254
diff --git a/doc/samples/keepalived.conf.virtual_server_group b/doc/samples/keepalived.conf.virtual_server_group
new file mode 100644 (file)
index 0000000..a01a329
--- /dev/null
@@ -0,0 +1,54 @@
+! Configuration File for keepalived
+
+global_defs {
+   notification_email {
+     acassen
+   }
+   notification_email_from Alexandre.Cassen@firewall.loc
+   smtp_server 192.168.200.1
+   smtp_connect_timeout 30
+   lvs_id LVS_DEVEL
+}
+
+virtual_server_group VSG_1 {
+       10.0.0.1 8080
+       10.0.0.2 80
+       192.168.200.1 1358
+       192.168.200.3-10 80
+       fwmark 1
+       fwmark 2
+}
+
+virtual_server group VSG_1 {
+    delay_loop 6
+    lb_algo rr 
+    lb_kind NAT
+    persistence_timeout 50
+    protocol TCP
+
+    real_server 192.168.200.1 1358 {
+        weight 1
+        HTTP_GET {
+            url { 
+              path /testurl3/test.jsp
+              digest 640205b7b0fc66c1ea91c463fac6334d
+            }
+            connect_timeout 3
+            nb_get_retry 3
+            delay_before_retry 3
+        }
+    }
+
+    real_server 192.168.200.2 1358 {
+        weight 1
+        HTTP_GET {
+            url { 
+              path /testurl3/test.jsp
+              digest 640205b7b0fc66c1ea91c463fac6334d
+            }
+            connect_timeout 3
+            nb_get_retry 3
+            delay_before_retry 3
+        }
+    }
+}
index 928db43..ca4f103 100644 (file)
@@ -1,7 +1,7 @@
 Name: keepalived
 Summary: HA monitor built upon LVS, VRRP and services poller
 Packager: Christophe Varoqui, <christophe.varoqui@free.fr>
-Version: 1.0.1
+Version: 1.0.2
 Release: 1
 Source: http://www.keepalived.org/software/%{name}-%{version}.tar.gz
 Copyright: GPL
index b5b8701..c552e1a 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Part:        Main program structure.
  *
- * Version:     $Id: main.c,v 1.0.1 2003/03/17 22:14:34 acassen Exp $
+ * Version:     $Id: main.c,v 1.0.2 2003/04/14 02:35:12 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
index c7e0bf9..7f2e5d4 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Part:        Dynamic data structure definition.
  *
- * Version:     $Id: data.c,v 1.0.1 2003/03/17 22:14:34 acassen Exp $
+ * Version:     $Id: data.c,v 1.0.2 2003/04/14 02:35:12 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
@@ -288,11 +288,92 @@ alloc_vrrp_vroute(vector strvec)
 }
 #endif
 
+/* Virtual server group facility functions */
+static void
+free_vsg(void *data)
+{
+       virtual_server_group *vsg = data;
+       FREE_PTR(vsg->gname);
+       free_list(vsg->addr_ip);
+       free_list(vsg->range);
+       free_list(vsg->vfwmark);
+       FREE(vsg);
+}
+static void
+dump_vsg(void *data)
+{
+       virtual_server_group *vsg = data;
+
+       syslog(LOG_INFO, " Virtual Server Group = %s", vsg->gname);
+       dump_list(vsg->addr_ip);
+       dump_list(vsg->range);
+       dump_list(vsg->vfwmark);
+}
+static void
+free_vsg_entry(void *data)
+{
+       FREE(data);
+}
+static void
+dump_vsg_entry(void *data)
+{
+       virtual_server_group_entry *vsg_entry = data;
+
+       if (vsg_entry->vfwmark)
+               syslog(LOG_INFO, "   FWMARK = %d", vsg_entry->vfwmark);
+       else if (vsg_entry->range)
+               syslog(LOG_INFO, "   VIP Range = %s-%d, VPORT = %d"
+                      , inet_ntop2(SVR_IP(vsg_entry))
+                      , vsg_entry->range
+                      , ntohs(SVR_PORT(vsg_entry)));
+       else
+               syslog(LOG_INFO, "   VIP = %s, VPORT = %d"
+                      , inet_ntop2(SVR_IP(vsg_entry))
+                      , ntohs(SVR_PORT(vsg_entry)));
+}
+void
+alloc_vsg(char *gname)
+{
+       int size = strlen(gname);
+       virtual_server_group *new;
+
+       new = (virtual_server_group *) MALLOC(sizeof (virtual_server_group));
+       new->gname = (char *) MALLOC(size + 1);
+       memcpy(new->gname, gname, size);
+       new->addr_ip = alloc_list(free_vsg_entry, dump_vsg_entry);
+       new->range = alloc_list(free_vsg_entry, dump_vsg_entry);
+       new->vfwmark = alloc_list(free_vsg_entry, dump_vsg_entry);
+
+       list_add(conf_data->vs_group, new);
+}
+void
+alloc_vsg_entry(vector strvec)
+{
+       virtual_server_group *vsg = LIST_TAIL_DATA(conf_data->vs_group);
+       virtual_server_group_entry *new;
+
+       new = (virtual_server_group_entry *) MALLOC(sizeof (virtual_server_group_entry));
+
+       if (!strcmp(VECTOR_SLOT(strvec, 0), "fwmark")) {
+               new->vfwmark = atoi(VECTOR_SLOT(strvec, 1));
+               list_add(vsg->vfwmark, new);
+       } else {
+               inet_ston(VECTOR_SLOT(strvec, 0), &new->addr_ip);
+               new->range = inet_stor(VECTOR_SLOT(strvec, 0));
+               new->addr_port = htons(atoi(VECTOR_SLOT(strvec, 1)));
+               if (!new->range)
+                       list_add(vsg->addr_ip, new);
+               else
+                       list_add(vsg->range, new);
+       }
+}
+
 /* Virtual server facility functions */
 static void
 free_vs(void *data)
 {
        virtual_server *vs = data;
+       FREE_PTR(vs->vsgname);
        FREE_PTR(vs->virtualhost);
        FREE_PTR(vs->s_svr);
        if (!LIST_ISEMPTY(vs->rs))
@@ -304,7 +385,9 @@ dump_vs(void *data)
 {
        virtual_server *vs = data;
 
-       if (vs->vfwmark)
+       if (vs->vsgname)
+               syslog(LOG_INFO, " VS GROUP = %s", vs->vsgname);
+       else if (vs->vfwmark)
                syslog(LOG_INFO, " VS FWMARK = %d", vs->vfwmark);
        else
                syslog(LOG_INFO, " VIP = %s, VPORT = %d", inet_ntop2(SVR_IP(vs))
@@ -364,11 +447,15 @@ dump_vs(void *data)
 void
 alloc_vs(char *ip, char *port)
 {
+       int size = strlen(port);
        virtual_server *new;
 
        new = (virtual_server *) MALLOC(sizeof (virtual_server));
 
-       if (!strcmp(ip, "fwmark")) {
+       if (!strcmp(ip, "group")) {
+               new->vsgname = (char *) MALLOC(size + 1);
+               memcpy(new->vsgname, port, size);
+       } else if (!strcmp(ip, "fwmark")) {
                new->vfwmark = atoi(port);
        } else {
                inet_ston(ip, &new->addr_ip);
@@ -450,6 +537,7 @@ alloc_data(void)
        new->vrrp_sync_group = alloc_list(free_vgroup, dump_vgroup);
 #endif
        new->vs = alloc_list(free_vs, dump_vs);
+       new->vs_group = alloc_list(free_vsg, dump_vsg);
 
        return new;
 }
@@ -463,6 +551,7 @@ free_data(data * data)
        free_list(data->vrrp_sync_group);
 #endif
        free_list(data->vs);
+       free_list(data->vs_group);
 
        FREE_PTR(data->lvs_id);
        FREE_PTR(data->email_from);
@@ -511,6 +600,8 @@ dump_data(data * data)
                syslog(LOG_INFO, "------< LVS Topology >------");
                syslog(LOG_INFO, " System is compiled with LVS v%d.%d.%d",
                       NVERSION(IP_VS_VERSION_CODE));
+               if (!LIST_ISEMPTY(data->vs_group))
+                       dump_list(data->vs_group);
                dump_list(data->vs);
        }
        dump_checkers_queue();
index bd88f79..33f6afc 100644 (file)
@@ -6,7 +6,7 @@
  * Part:        Layer4 checkers handling. Register worker threads &
  *              upper layer checkers.
  *
- * Version:     $Id: layer4.c,v 1.0.1 2003/03/17 22:14:34 acassen Exp $
+ * Version:     $Id: layer4.c,v 1.0.2 2003/04/14 02:35:12 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
index 9265404..81807b5 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Part:        Main program structure.
  *
- * Version:     $Id: main.c,v 1.0.1 2003/03/17 22:14:34 acassen Exp $
+ * Version:     $Id: main.c,v 1.0.2 2003/04/14 02:35:12 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
@@ -180,14 +180,14 @@ sigend(int sig)
 }
 
 /*
- * SIGCHLD handler. Reap any zombie child.
+ * SIGCHLD handler. Reap all zombie child.
  * WNOHANG prevent against parent process get
  * stuck waiting child termination.
  */
 void
 sigchld(int sig)
 {
-       waitpid(-1, NULL, WNOHANG);
+       while (waitpid(-1, NULL, WNOHANG) > 0);
 }
 
 /* Signal wrapper */
index 9856d0f..fafab18 100644 (file)
@@ -7,7 +7,7 @@
  *              data structure representation the conf file representing
  *              the loadbalanced server pool.
  *  
- * Version:     $Id: parser.c,v 1.0.1 2003/03/17 22:14:34 acassen Exp $
+ * Version:     $Id: parser.c,v 1.0.2 2003/04/14 02:35:12 acassen Exp $
  * 
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *              
@@ -229,6 +229,34 @@ read_value_block(void)
        return elements;
 }
 
+static void
+alloc_value_block(vector strvec, void (*alloc_func) (vector))
+{
+       char *buf;
+       char *str = NULL;
+       vector vec = NULL;
+
+       buf = (char *) MALLOC(MAXBUF);
+       while (read_line(buf, MAXBUF)) {
+               vec = alloc_strvec(buf);
+               if (vec) {
+                       str = VECTOR_SLOT(vec, 0);
+                       if (!strcmp(str, EOB)) {
+                               free_strvec(vec);
+                               break;
+                       }
+
+                       if (VECTOR_SIZE(vec))
+                               (*alloc_func) (vec);
+
+                       free_strvec(vec);
+               }
+               memset(buf, 0, MAXBUF);
+       }
+       FREE(buf);
+}
+
+
 void *
 set_value(vector strvec)
 {
@@ -335,28 +363,7 @@ sslkey_handler(vector strvec)
 static void
 static_routes_handler(vector strvec)
 {
-       char *buf;
-       char *str = NULL;
-       vector vec = NULL;
-
-       buf = (char *) MALLOC(MAXBUF);
-       while (read_line(buf, MAXBUF)) {
-               vec = alloc_strvec(buf);
-               if (vec) {
-                       str = VECTOR_SLOT(vec, 0);
-                       if (!strcmp(str, EOB)) {
-                               free_strvec(vec);
-                               break;
-                       }
-
-                       if (VECTOR_SIZE(vec))
-                               alloc_sroute(vec);
-
-                       free_strvec(vec);
-               }
-               memset(buf, 0, MAXBUF);
-       }
-       FREE(buf);
+       alloc_value_block(strvec, alloc_sroute);
 }
 
 /* VRRP handlers */
@@ -602,60 +609,25 @@ vrrp_vip_handler(vector strvec)
 static void
 vrrp_evip_handler(vector strvec)
 {
-       char *buf;
-       char *str = NULL;
-       vector vec = NULL;
-
-       buf = (char *) MALLOC(MAXBUF);
-       while (read_line(buf, MAXBUF)) {
-               vec = alloc_strvec(buf);
-               if (vec) {
-                       str = VECTOR_SLOT(vec, 0);
-                       if (!strcmp(str, EOB)) {
-                               free_strvec(vec);
-                               break;
-                       }
-
-                       if (VECTOR_SIZE(vec))
-                               alloc_vrrp_evip(vec);
-
-                       free_strvec(vec);
-               }
-               memset(buf, 0, MAXBUF);
-       }
-       FREE(buf);
+       alloc_value_block(strvec, alloc_vrrp_evip);
 }
 static void
 vrrp_vroutes_handler(vector strvec)
 {
-       char *buf;
-       char *str = NULL;
-       vector vec = NULL;
-
-       buf = (char *) MALLOC(MAXBUF);
-       while (read_line(buf, MAXBUF)) {
-               vec = alloc_strvec(buf);
-               if (vec) {
-                       str = VECTOR_SLOT(vec, 0);
-                       if (!strcmp(str, EOB)) {
-                               free_strvec(vec);
-                               break;
-                       }
-
-                       if (VECTOR_SIZE(vec))
-                               alloc_vrrp_vroute(vec);
-
-                       free_strvec(vec);
-               }
-               memset(buf, 0, MAXBUF);
-       }
-       FREE(buf);
+       alloc_value_block(strvec, alloc_vrrp_vroute);
 }
 #endif
 
 #ifdef _WITH_LVS_
 /* Virtual Servers handlers */
 static void
+vsg_handler(vector strvec)
+{
+       /* Fetch queued vsg */
+       alloc_vsg(VECTOR_SLOT(strvec, 1));
+       alloc_value_block(strvec, alloc_vsg_entry);
+}
+static void
 vs_handler(vector strvec)
 {
        alloc_vs(VECTOR_SLOT(strvec, 1), VECTOR_SLOT(strvec, 2));
@@ -890,6 +862,7 @@ init_keywords(void)
 
 #ifdef _WITH_LVS_
        /* Virtual server mapping */
+       install_keyword_root("virtual_server_group", &vsg_handler);
        install_keyword_root("virtual_server", &vs_handler);
        install_keyword("delay_loop", &delay_handler);
        install_keyword("lb_algo", &lbalgo_handler);
index 7e40247..d729bdd 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Part:        pidfile utility.
  *
- * Version:     $Id: pidfile.c,v 1.0.1 2003/03/17 22:14:34 acassen Exp $
+ * Version:     $Id: pidfile.c,v 1.0.2 2003/04/14 02:35:12 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
index 2f51dad..a4fdd08 100644 (file)
@@ -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 1.0.1 2003/03/17 22:14:34 acassen Exp $
+ * Version:     $Id: smtp.c,v 1.0.2 2003/04/14 02:35:12 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
index fce9a00..927cc11 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Part:        Checkers registration.
  *
- * Version:     $Id: check_api.c,v 1.0.1 2003/03/17 22:14:34 acassen Exp $
+ * Version:     $Id: check_api.c,v 1.0.2 2003/04/14 02:35:12 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
index 11ca4ff..60effb4 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Part:        CI-LINUX checker. Integration to Compaq Cluster Infrastructure.
  *
- * Version:     $Id: check_ci.c,v 1.0.1 2003/03/17 22:14:34 acassen Exp $
+ * Version:     $Id: check_ci.c,v 1.0.2 2003/04/14 02:35:12 acassen Exp $
  *
  * Authors:     Alexandre Cassen, <acassen@linux-vs.org>
  *              Aneesh Kumar K.V, <aneesh.kumar@digital.com>
index dc03511..fe3c367 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Part:        WEB CHECK. Common HTTP/SSL checker primitives.
  *
- * Version:     $Id: check_http.c,v 1.0.1 2003/03/17 22:14:34 acassen Exp $
+ * Version:     $Id: check_http.c,v 1.0.2 2003/04/14 02:35:12 acassen Exp $
  *
  * Authors:     Alexandre Cassen, <acassen@linux-vs.org>
  *              Jan Holmberg, <jan@artech.net>
index b779676..484687f 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 1.0.1 2003/03/17 22:14:34 acassen Exp $
+ * Version:     $Id: check_misc.c,v 1.0.2 2003/04/14 02:35:12 acassen Exp $
  *
  * Authors:     Alexandre Cassen, <acassen@linux-vs.org>
  *              Eric Jarman, <ehj38230@cmsu2.cmsu.edu>
index 025bbc8..7c2cdf4 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 1.0.1 2003/03/17 22:14:34 acassen Exp $
+ * Version:     $Id: check_ssl.c,v 1.0.2 2003/04/14 02:35:12 acassen Exp $
  *
  * Authors:     Alexandre Cassen, <acassen@linux-vs.org>
  *              Jan Holmberg, <jan@artech.net>
index 2cb89f0..a05ba67 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Part:        TCP checker.
  *
- * Version:     $Id: check_tcp.c,v 1.0.1 2003/03/17 22:14:34 acassen Exp $
+ * Version:     $Id: check_tcp.c,v 1.0.2 2003/04/14 02:35:12 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
index 99992dc..eddabaf 100644 (file)
@@ -7,7 +7,7 @@
  *              library to add/remove server MASQ rules to the kernel 
  *              firewall framework.
  *
- * Version:     $Id: ipfwwrapper.c,v 1.0.1 2003/03/17 22:14:34 acassen Exp $
+ * Version:     $Id: ipfwwrapper.c,v 1.0.2 2003/04/14 02:35:12 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
index f7b1aac..0314c5d 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 1.0.1 2003/03/17 22:14:34 acassen Exp $
+ * Version:     $Id: ipvswrapper.c,v 1.0.2 2003/04/14 02:35:12 acassen Exp $
  * 
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *              
  *               2 of the License, or (at your option) any later version.
  */
 
+#include "data.h"
+#include "list.h"
 #include "ipvswrapper.h"
 #include "utils.h"
 #include "memory.h"
 
+/* external types */
+extern data *conf_data;
+
 /* local helpers functions */
 static int parse_timeout(char *, unsigned *);
 static int string_to_number(const char *, int, int);
@@ -40,7 +45,7 @@ ipvs_syncd_cmd(int cmd, char *ifname, int state)
 }
 
 int
-ipvs_cmd(int cmd, virtual_server * vs, real_server * rs)
+ipvs_cmd(int cmd, list vs_group, virtual_server * vs, real_server * rs)
 {
        struct ip_masq_ctl ctl;
        int result = 0;
@@ -127,8 +132,6 @@ ipvs_cmd(int cmd, virtual_server * vs, real_server * rs)
 }
 
 
-
-
 #else                          /* KERNEL 2.4 LVS handling */
 
 static int
@@ -177,14 +180,112 @@ ipvs_syncd_cmd(int cmd, char *ifname, int state)
 #endif
 }
 
-int
-ipvs_cmd(int cmd, virtual_server * vs, real_server * rs)
+/* fetch virtual server group from group name */
+virtual_server_group *
+ipvs_get_group_by_name(char *gname, list l)
 {
-       struct ip_vs_rule_user *urule;
+       element e;
+       virtual_server_group *vsg;
+
+       for (e = LIST_HEAD(l); e; ELEMENT_NEXT(e)) {
+               vsg = ELEMENT_DATA(e);
+               if (!strcmp(vsg->gname, gname))
+                       return vsg;
+       }
+       return NULL;
+}
+
+/* IPVS group range rule */
+static int
+ipvs_group_range_cmd(int cmd, struct ip_vs_rule_user *urule
+                    , virtual_server_group_entry *vsg_entry)
+{
+       uint32_t addr_ip;
        int err = 0;
 
+       /* Parse the whole range */
+       for (addr_ip = SVR_IP(vsg_entry);
+            ((addr_ip >> 24) & 0xFF) <= vsg_entry->range;
+            addr_ip += 0x01000000) {
+               urule->vaddr = addr_ip;
+               urule->vport = SVR_PORT(vsg_entry);
+
+               /* Talk to the IPVS channel */
+               err = ipvs_talk(cmd, urule);
+       }
+
+       return err;
+}
+
+/* set IPVS group rules */
+static int
+ipvs_group_cmd(int cmd, list vs_group, struct ip_vs_rule_user *urule, char * vsgname)
+{
+       virtual_server_group *vsg = ipvs_get_group_by_name(vsgname, vs_group);
+       virtual_server_group_entry *vsg_entry;
+       list l;
+       element e;
+       int err = 1;
+
+       /* return if jointure fails */
+       if (!vsg) return -1;
+
+       /* visit addr_ip list */
+       l = vsg->addr_ip;
+       for (e = LIST_HEAD(l); e; ELEMENT_NEXT(e)) {
+               vsg_entry = ELEMENT_DATA(e);
+               urule->vaddr = SVR_IP(vsg_entry);
+               urule->vport = SVR_PORT(vsg_entry);
+
+               /* Talk to the IPVS channel */
+               if (IPVS_ALIVE(cmd, vsg_entry)) {
+                       err = ipvs_talk(cmd, urule);
+                       if (cmd == IP_VS_SO_SET_ADD)
+                               SET_ALIVE(vsg_entry);
+               }
+       }
+
+       /* visit vfwmark list */
+       l = vsg->vfwmark;
+       urule->vaddr = 0;
+       urule->vport = 0;
+       for (e = LIST_HEAD(l); e; ELEMENT_NEXT(e)) {
+               vsg_entry = ELEMENT_DATA(e);
+               urule->vfwmark = vsg_entry->vfwmark;
+
+               /* Talk to the IPVS channel */
+               if (IPVS_ALIVE(cmd, vsg_entry)) {
+                       err = ipvs_talk(cmd, urule);
+                       if (cmd == IP_VS_SO_SET_ADD)
+                               SET_ALIVE(vsg_entry);
+               }
+       }
+
+       /* visit range list */
+       l = vsg->range;
+       urule->vfwmark = 0;
+       for (e = LIST_HEAD(l); e; ELEMENT_NEXT(e)) {
+               vsg_entry = ELEMENT_DATA(e);
+
+               /* Talk to the IPVS channel */
+               if (IPVS_ALIVE(cmd, vsg_entry)) {
+                       err = ipvs_group_range_cmd(cmd, urule, vsg_entry);
+                       if (cmd == IP_VS_SO_SET_ADD)
+                               SET_ALIVE(vsg_entry);
+               }
+       }
+
+       return err;
+}
+
+/* Fill IPVS rule with root vs infos */
+struct ip_vs_rule_user *
+ipvs_set_rule(int cmd, virtual_server * vs, real_server * rs)
+{
+       struct ip_vs_rule_user *urule;
+
+       /* Allocate target rule */
        urule = (struct ip_vs_rule_user *) MALLOC(sizeof (struct ip_vs_rule_user));
-       memset(urule, 0, sizeof (struct ip_vs_rule_user));
 
        strncpy(urule->sched_name, vs->sched, IP_VS_SCHEDNAME_MAXLEN);
        urule->weight = 1;
@@ -200,25 +301,29 @@ ipvs_cmd(int cmd, virtual_server * vs, real_server * rs)
        if (urule->timeout != 0 || vs->granularity_persistence)
                urule->vs_flags = IP_VS_SVC_F_PERSISTENT;
 
-       /* VS specific */
-       if (vs->vfwmark) {
-               urule->vfwmark = vs->vfwmark;
-       } else {
-               urule->vaddr = SVR_IP(vs);
-               urule->vport = SVR_PORT(vs);
-       }
-
        if (cmd == IP_VS_SO_SET_ADD || cmd == IP_VS_SO_SET_DEL)
                if (vs->granularity_persistence)
                        urule->netmask = vs->granularity_persistence;
 
        /* SVR specific */
-       if (cmd == IP_VS_SO_SET_ADDDEST || cmd == IP_VS_SO_SET_DELDEST) {
-               urule->weight = rs->weight;
-               urule->daddr = SVR_IP(rs);
-               urule->dport = SVR_PORT(rs);
+       if (rs) {
+               if (cmd == IP_VS_SO_SET_ADDDEST || cmd == IP_VS_SO_SET_DELDEST) {
+                       urule->weight = rs->weight;
+                       urule->daddr = SVR_IP(rs);
+                       urule->dport = SVR_PORT(rs);
+               }
        }
 
+       return urule;
+}
+
+/* Set/Remove a RS from a VS */
+int
+ipvs_cmd(int cmd, list vs_group, virtual_server * vs, real_server * rs)
+{
+       struct ip_vs_rule_user *urule = ipvs_set_rule(cmd, vs, rs);
+       int err = 0;
+
        /* Does the service use inhibit flag ? */
        if (cmd == IP_VS_SO_SET_DELDEST && rs->inhibit) {
                urule->weight = 0;
@@ -227,8 +332,69 @@ ipvs_cmd(int cmd, virtual_server * vs, real_server * rs)
        if (cmd == IP_VS_SO_SET_ADDDEST && rs->inhibit && rs->alive)
                cmd = IP_VS_SO_SET_EDITDEST;
 
-       /* Talk to the IPVS channel */
-       err = ipvs_talk(cmd, urule);
+       /* Set vs rule and send to kernel */
+       if (vs->vsgname) {
+               err = ipvs_group_cmd(cmd, vs_group, urule, vs->vsgname);
+       } else {
+               if (vs->vfwmark) {
+                       urule->vfwmark = vs->vfwmark;
+               } else {
+                       urule->vaddr = SVR_IP(vs);
+                       urule->vport = SVR_PORT(vs);
+               }
+
+               /* Talk to the IPVS channel */
+               err = ipvs_talk(cmd, urule);
+       }
+
+       FREE(urule);
+       return err;
+}
+
+/* Remove a specific vs group entry */
+int
+ipvs_group_remove_entry(virtual_server *vs, virtual_server_group_entry *vsge)
+{
+       struct ip_vs_rule_user *urule = NULL;
+       real_server *rs;
+       int err = 0;
+       element e;
+       list l = vs->rs;
+
+       /* Process realserver queue */
+       for (e = LIST_HEAD(l); e; ELEMENT_NEXT(e)) {
+               rs = ELEMENT_DATA(e);
+
+               if (rs->alive) {
+                       /* Prepare the IPVS rule */
+                       if (!urule) {
+                               /* Setting IPVS rule with vs root rs */
+                               urule = ipvs_set_rule(IP_VS_SO_SET_DELDEST, vs, rs);
+                       } else {
+                               urule->weight = rs->weight;
+                               urule->daddr = SVR_IP(rs);
+                               urule->dport = SVR_PORT(rs);
+                       }
+
+                       /* Set vs rule */
+                       if (vsge->range) {
+                               ipvs_group_range_cmd(IP_VS_SO_SET_DELDEST, urule, vsge);
+                       } else {
+                               urule->vfwmark = vsge->vfwmark;
+                               urule->vaddr = SVR_IP(vsge);
+                               urule->vport = SVR_PORT(vsge);
+
+                               /* Talk to the IPVS channel */
+                               err = ipvs_talk(IP_VS_SO_SET_DELDEST, urule);
+                       }
+               }
+       }
+
+       /* Remove VS entry */
+       if (vsge->range)
+               err = ipvs_group_range_cmd(IP_VS_SO_SET_DEL, urule, vsge);
+       else
+               err = ipvs_talk(IP_VS_SO_SET_DEL, urule);
 
        FREE(urule);
        return err;
index c7bd1f1..661d2e5 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Part:        Manipulation functions for IPVS & IPFW wrappers.
  *
- * Version:     $id: ipwrapper.c,v 1.0.1 2003/03/17 22:14:34 acassen Exp $
+ * Version:     $id: ipwrapper.c,v 1.0.2 2003/04/14 02:35:12 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
@@ -21,6 +21,7 @@
  */
 
 #include "ipwrapper.h"
+#include "ipvswrapper.h"
 #include "utils.h"
 #include "notify.h"
 
@@ -30,16 +31,21 @@ extern data *old_data;
 
 /* Remove a realserver IPVS rule */
 static int
-clear_service_rs(virtual_server * vs, list l)
+clear_service_rs(list vs_group, virtual_server * vs, list l)
 {
        element e;
        real_server *rs;
 
        for (e = LIST_HEAD(l); e; ELEMENT_NEXT(e)) {
                rs = ELEMENT_DATA(e);
-               if (ISALIVE(rs))
-                       if (!ipvs_cmd(LVS_CMD_DEL_DEST, vs, rs))
+               if (ISALIVE(rs)) {
+                       if (!ipvs_cmd(LVS_CMD_DEL_DEST
+                                     , vs_group
+                                     , vs
+                                     , rs))
                                return 0;
+                       UNSET_ALIVE(rs);
+               }
 #ifdef _KRNL_2_2_
                /* if we have a /32 mask, we create one nat rules per
                 * realserver.
@@ -54,20 +60,25 @@ clear_service_rs(virtual_server * vs, list l)
 
 /* Remove a virtualserver IPVS rule */
 static int
-clear_service_vs(virtual_server * vs)
+clear_service_vs(list vs_group, virtual_server * vs)
 {
        /* Processing real server queue */
        if (!LIST_ISEMPTY(vs->rs)) {
                if (vs->s_svr) {
                        if (ISALIVE(vs->s_svr))
-                               if (!ipvs_cmd(LVS_CMD_DEL_DEST, vs, vs->s_svr))
+                               if (!ipvs_cmd(LVS_CMD_DEL_DEST
+                                             , vs_group
+                                             , vs
+                                             , vs->s_svr))
                                        return 0;
-               } else if (!clear_service_rs(vs, vs->rs))
+               } else if (!clear_service_rs(vs_group, vs, vs->rs))
                        return 0;
        }
 
-       if (!ipvs_cmd(LVS_CMD_DEL, vs, NULL))
+       if (!ipvs_cmd(LVS_CMD_DEL, vs_group, vs, NULL))
                return 0;
+
+       UNSET_ALIVE(vs);
        return 1;
 }
 
@@ -83,7 +94,7 @@ clear_services(void)
        for (e = LIST_HEAD(l); e; ELEMENT_NEXT(e)) {
                vs = ELEMENT_DATA(e);
                rs = ELEMENT_DATA(LIST_HEAD(vs->rs));
-               if (!clear_service_vs(vs))
+               if (!clear_service_vs(conf_data->vs_group, vs))
                        return 0;
 #ifdef _KRNL_2_2_
                if (vs->nat_mask != HOST_NETMASK)
@@ -94,6 +105,43 @@ clear_services(void)
        return 1;
 }
 
+/* Set rsalive flag if vs is a group */
+static int
+set_group_rsalive(virtual_server * vs, list group, int set)
+{
+       virtual_server_group *vsg = ipvs_get_group_by_name(vs->vsgname, group);
+       virtual_server_group_entry *vsg_entry;
+       list l;
+       element e;
+
+       /* return if jointure fails */
+       if (!vsg)
+               return 0;
+
+       /* visit addr_ip list */
+       l = vsg->addr_ip;
+       for (e = LIST_HEAD(l); e; ELEMENT_NEXT(e)) {
+               vsg_entry = ELEMENT_DATA(e);
+               vsg_entry->rsalive = set;
+       }
+
+       /* visit vfwmark list */
+       l = vsg->vfwmark;
+       for (e = LIST_HEAD(l); e; ELEMENT_NEXT(e)) {
+               vsg_entry = ELEMENT_DATA(e);
+               vsg_entry->rsalive = set;
+       }
+
+       /* visit range list */
+       l = vsg->range;
+       for (e = LIST_HEAD(l); e; ELEMENT_NEXT(e)) {
+               vsg_entry = ELEMENT_DATA(e);
+               vsg_entry->rsalive = set;
+       }
+
+       return 1;
+}
+
 /* Set a realserver IPVS rules */
 static int
 init_service_rs(virtual_server * vs, list l)
@@ -104,10 +152,19 @@ init_service_rs(virtual_server * vs, list l)
        for (e = LIST_HEAD(l); e; ELEMENT_NEXT(e)) {
                rs = ELEMENT_DATA(e);
                if (!ISALIVE(rs)) {
-                       if (!ipvs_cmd(LVS_CMD_ADD_DEST, vs, rs))
+                       /* flush rsalive flag */
+                       if (vs->vsgname)
+                               set_group_rsalive(vs, conf_data->vs_group, 0);
+
+                       if (!ipvs_cmd(LVS_CMD_ADD_DEST, conf_data->vs_group, vs, rs))
                                return 0;
                        else
                                SET_ALIVE(rs);
+               } else if (vs->vsgname) {
+                       UNSET_ALIVE(rs);
+                       if (!ipvs_cmd(LVS_CMD_ADD_DEST, conf_data->vs_group, vs, rs))
+                               return 0;
+                       SET_ALIVE(rs);
                }
 #ifdef _KRNL_2_2_
                /* if we have a /32 mask, we create one nat rules per
@@ -118,6 +175,14 @@ init_service_rs(virtual_server * vs, list l)
                                return 0;
 #endif
        }
+
+       /*
+        * All rs entries have been set,
+        * set rsalive flag for all vsg entries.
+        */
+       if (vs->vsgname)
+               set_group_rsalive(vs, conf_data->vs_group, 1);
+
        return 1;
 }
 
@@ -126,8 +191,8 @@ static int
 init_service_vs(virtual_server * vs)
 {
        /* Init the VS root */
-       if (!ISALIVE(vs)) {
-               if (!ipvs_cmd(LVS_CMD_ADD, vs, NULL))
+       if (!ISALIVE(vs) || vs->vsgname) {
+               if (!ipvs_cmd(LVS_CMD_ADD, conf_data->vs_group, vs, NULL))
                        return 0;
                else
                        SET_ALIVE(vs);
@@ -199,11 +264,14 @@ perform_svr_state(int alive, virtual_server * vs, real_server * rs)
                                       "Removing sorry server [%s:%d] from VS [%s:%d]",
                                       inet_ntoa2(SVR_IP(vs->s_svr), rsip)
                                       , ntohs(SVR_PORT(vs->s_svr))
-                                      , inet_ntoa2(SVR_IP(vs), vsip)
+                                      , (vs->vsgname) ? vs->vsgname : inet_ntoa2(SVR_IP(vs), vsip)
                                       , ntohs(SVR_PORT(vs)));
 
                                vs->s_svr->alive = 0;
-                               ipvs_cmd(LVS_CMD_DEL_DEST, vs, vs->s_svr);
+                               ipvs_cmd(LVS_CMD_DEL_DEST
+                                        , conf_data->vs_group
+                                        , vs
+                                        , vs->s_svr);
 #ifdef _KRNL_2_2_
                                ipfw_cmd(IP_FW_CMD_DEL, vs, vs->s_svr);
 #endif
@@ -215,16 +283,16 @@ perform_svr_state(int alive, virtual_server * vs, real_server * rs)
                       (rs->inhibit) ? "Enabling" : "Adding"
                       , inet_ntoa2(SVR_IP(rs), rsip)
                       , ntohs(SVR_PORT(rs))
-                      , inet_ntoa2(SVR_IP(vs), vsip)
+                      , (vs->vsgname) ? vs->vsgname : inet_ntoa2(SVR_IP(vs), vsip)
                       , ntohs(SVR_PORT(vs)));
-               ipvs_cmd(LVS_CMD_ADD_DEST, vs, rs);
+               ipvs_cmd(LVS_CMD_ADD_DEST, conf_data->vs_group, vs, rs);
                if (rs->notify_up) {
                        syslog(LOG_INFO, "Executing [%s] for service [%s:%d]"
                               " in VS [%s:%d]"
                               , rs->notify_up
                               , inet_ntoa2(SVR_IP(rs), rsip)
                               , ntohs(SVR_PORT(rs))
-                              , inet_ntoa2(SVR_IP(vs), vsip)
+                              , (vs->vsgname) ? vs->vsgname : inet_ntoa2(SVR_IP(vs), vsip)
                               , ntohs(SVR_PORT(vs)));
                        notify_exec(rs->notify_up);
                }
@@ -240,18 +308,18 @@ perform_svr_state(int alive, virtual_server * vs, real_server * rs)
                       (rs->inhibit) ? "Disabling" : "Removing"
                       , inet_ntoa2(SVR_IP(rs), rsip)
                       , ntohs(SVR_PORT(rs))
-                      , inet_ntoa2(SVR_IP(vs), vsip)
+                      , (vs->vsgname) ? vs->vsgname : inet_ntoa2(SVR_IP(vs), vsip)
                       , ntohs(SVR_PORT(vs)));
 
                /* server is down, it is removed from the LVS realserver pool */
-               ipvs_cmd(LVS_CMD_DEL_DEST, vs, rs);
+               ipvs_cmd(LVS_CMD_DEL_DEST, conf_data->vs_group, vs, rs);
                if (rs->notify_down) {
                        syslog(LOG_INFO, "Executing [%s] for service [%s:%d]"
                               " in VS [%s:%d]"
                               , rs->notify_down
                               , inet_ntoa2(SVR_IP(rs), rsip)
                               , ntohs(SVR_PORT(rs))
-                              , inet_ntoa2(SVR_IP(vs), vsip)
+                              , (vs->vsgname) ? vs->vsgname : inet_ntoa2(SVR_IP(vs), vsip)
                               , ntohs(SVR_PORT(vs)));
                        notify_exec(rs->notify_down);
                }
@@ -267,12 +335,12 @@ perform_svr_state(int alive, virtual_server * vs, real_server * rs)
                               "Adding sorry server [%s:%d] to VS [%s:%d]",
                               inet_ntoa2(SVR_IP(vs->s_svr), rsip)
                               , ntohs(SVR_PORT(vs->s_svr))
-                              , inet_ntoa2(SVR_IP(vs), vsip)
+                              , (vs->vsgname) ? vs->vsgname : inet_ntoa2(SVR_IP(vs), vsip)
                               , ntohs(SVR_PORT(vs)));
 
                        /* the sorry server is now up in the pool, we flag it alive */
                        vs->s_svr->alive = 1;
-                       ipvs_cmd(LVS_CMD_ADD_DEST, vs, vs->s_svr);
+                       ipvs_cmd(LVS_CMD_ADD_DEST, conf_data->vs_group, vs, vs->s_svr);
 
 #ifdef _KRNL_2_2_
                        ipfw_cmd(IP_FW_CMD_ADD, vs, vs->s_svr);
@@ -282,32 +350,76 @@ perform_svr_state(int alive, virtual_server * vs, real_server * rs)
        }
 }
 
-/* Check if rs1 = rs2 */
+/* Check if a vsg entry is in new data */
 static int
-rs_iseq(real_server * rs1, real_server * rs2)
+vsge_exist(virtual_server_group_entry *vsg_entry, list l)
 {
-       if (rs1->addr_ip == rs2->addr_ip &&
-           rs1->addr_port == rs2->addr_port &&
-           rs1->weight == rs2->weight)
-               return 1;
+       element e;
+       virtual_server_group_entry *vsge;
+
+       for (e = LIST_HEAD(l); e; ELEMENT_NEXT(e)) {
+               vsge = ELEMENT_DATA(e);
+               if (VSGE_ISEQ(vsg_entry, vsge)) {
+                       /*
+                        * If vsge exist this entry
+                        * is alive since only rs entries
+                        * are changing from alive state.
+                        */
+                       SET_ALIVE(vsge);
+                       SET_RSALIVE(vsge);
+                       return 1;
+               }
+       }
+
        return 0;
 }
 
-/* Check if vs1 = vs2 */
+/* Clear the diff vsge of old group */
 static int
-vs_iseq(virtual_server * vs1, virtual_server * vs2)
+clear_diff_vsge(list old, list new, virtual_server * old_vs)
 {
-       if (vs1->addr_ip == vs2->addr_ip &&
-           vs1->vfwmark == vs2->vfwmark &&
-           vs1->addr_port == vs2->addr_port &&
-           vs1->service_type == vs2->service_type &&
-           !strcmp(vs1->sched, vs2->sched) &&
-           !strcmp(vs1->timeout_persistence, vs2->timeout_persistence) &&
-           vs1->loadbalancing_kind == vs2->loadbalancing_kind &&
-           vs1->nat_mask == vs2->nat_mask &&
-           vs1->granularity_persistence == vs2->granularity_persistence)
-               return 1;
-       return 0;
+       element e;
+       virtual_server_group_entry *vsge;
+
+       for (e = LIST_HEAD(old); e; ELEMENT_NEXT(e)) {
+               vsge = ELEMENT_DATA(e);
+               if (!vsge_exist(vsge, new)) {
+                       syslog(LOG_INFO, "VS [%s:%d:%d:%d] in group %s"
+                              " no longer exist\n" 
+                              , inet_ntop2(vsge->addr_ip)
+                              , ntohs(vsge->addr_port)
+                              , vsge->range
+                              , vsge->vfwmark
+                              , old_vs->vsgname);
+
+                       if (!ipvs_group_remove_entry(old_vs, vsge))
+                               return 0;
+               }
+       }
+
+       return 1;
+}
+
+/* Clear the diff vsg of the old vs */
+static int
+clear_diff_vsg(virtual_server * old_vs)
+{
+       virtual_server_group *old;
+       virtual_server_group *new;
+
+       /* Fetch group */
+       old = ipvs_get_group_by_name(old_vs->vsgname, old_data->vs_group);
+       new = ipvs_get_group_by_name(old_vs->vsgname, conf_data->vs_group);
+
+       /* Diff the group entries */
+       if (!clear_diff_vsge(old->addr_ip, new->addr_ip, old_vs))
+               return 0;
+       if (!clear_diff_vsge(old->range, new->range, old_vs))
+               return 0;
+       if (!clear_diff_vsge(old->vfwmark, new->vfwmark, old_vs))
+               return 0;
+
+       return 1;
 }
 
 /* Check if a vs exist in new data */
@@ -317,16 +429,26 @@ vs_exist(virtual_server * old_vs)
        element e;
        list l = conf_data->vs;
        virtual_server *vs;
+       virtual_server_group *vsg;
 
        for (e = LIST_HEAD(l); e; ELEMENT_NEXT(e)) {
                vs = ELEMENT_DATA(e);
-               if (vs_iseq(old_vs, vs)) {
+               if (VS_ISEQ(old_vs, vs)) {
+                       /* Check if group exist */
+                       if (vs->vsgname) {
+                               vsg = ipvs_get_group_by_name(old_vs->vsgname,
+                                                           conf_data->vs_group);
+                               if (!vsg)
+                                       return 0;
+                               else
+                                       if (!clear_diff_vsg(old_vs))
+                                               return 0;       
+                       }
+
                        /*
-                        * We reflect the previous alive
-                        * flag value to not try to set
-                        * already set IPVS rule.
+                        * Exist so set alive.
                         */
-                       vs->alive = old_vs->alive;
+                       SET_ALIVE(vs);
                        return 1;
                }
        }
@@ -343,7 +465,7 @@ rs_exist(real_server * old_rs, list l)
 
        for (e = LIST_HEAD(l); e; ELEMENT_NEXT(e)) {
                rs = ELEMENT_DATA(e);
-               if (rs_iseq(rs, old_rs)) {
+               if (RS_ISEQ(rs, old_rs)) {
                        /*
                         * We reflect the previous alive
                         * flag value to not try to set
@@ -367,7 +489,7 @@ get_rs_list(virtual_server * vs)
 
        for (e = LIST_HEAD(l); e; ELEMENT_NEXT(e)) {
                vsrv = ELEMENT_DATA(e);
-               if (vs_iseq(vs, vsrv))
+               if (VS_ISEQ(vs, vsrv))
                        return vsrv->rs;
        }
 
@@ -387,7 +509,7 @@ clear_diff_rs(virtual_server * old_vs)
 
        for (e = LIST_HEAD(l); e; ELEMENT_NEXT(e)) {
                rs = ELEMENT_DATA(e);
-               if (!rs_exist(rs, new) && (ISALIVE(rs) || rs->inhibit)) {
+               if (!rs_exist(rs, new)) {
                        /* Reset inhibit flag to delete inhibit entries */
                        syslog(LOG_INFO, "service [%s:%d] no longer exist"
                               , inet_ntoa2(SVR_IP(rs), rsip)
@@ -398,15 +520,7 @@ clear_diff_rs(virtual_server * old_vs)
                               , inet_ntoa2(SVR_IP(old_vs), vsip)
                               , ntohs(SVR_PORT(old_vs)));
                        rs->inhibit = 0;
-                       if (!ipvs_cmd(LVS_CMD_DEL_DEST, old_vs, rs))
-                               return 0;
-               } else if (!ISALIVE(rs) && rs->inhibit) {
-                       /*
-                        * We duplicate here just for optimization. We
-                        * don t want to call rs_exist() 2 times.
-                        */
-                       rs->inhibit = 0;
-                       if (!ipvs_cmd(LVS_CMD_DEL_DEST, old_vs, rs))
+                       if (!ipvs_cmd(LVS_CMD_DEL_DEST, conf_data->vs_group, old_vs, rs))
                                return 0;
                }
        }
@@ -431,7 +545,16 @@ clear_diff_services(void)
                 * reloaded.
                 */
                if (!vs_exist(vs)) {
-                       if (!clear_service_vs(vs))
+                       if (vs->vsgname)
+                               syslog(LOG_INFO, "Removing Virtual Server Group [%s]"
+                                      , vs->vsgname);
+                       else
+                               syslog(LOG_INFO, "Removing Virtual Server [%s:%d]"
+                                      , inet_ntop2(vs->addr_ip)
+                                      , ntohs(vs->addr_port));
+
+                       /* Clear VS entry */
+                       if (!clear_service_vs(old_data->vs_group, vs))
                                return 0;
                } else {
                        /* If vs exist, perform rs pool diff */
@@ -439,8 +562,10 @@ clear_diff_services(void)
                                return 0;
                        if (vs->s_svr)
                                if (ISALIVE(vs->s_svr))
-                                       if (!ipvs_cmd(LVS_CMD_DEL_DEST, vs,
-                                                     vs->s_svr))
+                                       if (!ipvs_cmd(LVS_CMD_DEL_DEST
+                                                     , conf_data->vs_group
+                                                     , vs
+                                                     , vs->s_svr))
                                                return 0;
                }
        }
index bc91ac9..6cbbe14 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Part:        Checkers arguments structures definitions.
  *
- * Version:     $Id: check_api.h,v 1.0.1 2003/03/17 22:14:34 acassen Exp $
+ * Version:     $Id: check_api.h,v 1.0.2 2003/04/14 02:35:12 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
index 699a339..6f47bec 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Part:        check_ci.c include file.
  *
- * Version:     $Id: check_ci.h,v 1.0.1 2003/03/17 22:14:34 acassen Exp $
+ * Version:     $Id: check_ci.h,v 1.0.2 2003/04/14 02:35:12 acassen Exp $
  *
  * Authors:     Alexandre Cassen, <acassen@linux-vs.org>
  *              Aneesh Kumar K.V, <aneesh.kumar@digital.com>
index ed70572..f114bcd 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Part:        check_http.c include file.
  *
- * Version:     $Id: check_http.h,v 1.0.1 2003/03/17 22:14:34 acassen Exp $
+ * Version:     $Id: check_http.h,v 1.0.2 2003/04/14 02:35:12 acassen Exp $
  *
  * Authors:     Alexandre Cassen, <acassen@linux-vs.org>
  *              Jan Holmberg, <jan@artech.net>
index 80834d3..1f62898 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Part:        check_misc.c include file.
  *
- * Version:     $Id: check_misc.h,v 1.0.1 2003/03/17 22:14:34 acassen Exp $
+ * Version:     $Id: check_misc.h,v 1.0.2 2003/04/14 02:35:12 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *              Eric Jarman, <ehj38230@cmsu2.cmsu.edu>
index 7158b40..463c383 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Part:        check_http.c include file.
  *
- * Version:     $Id: check_http.h,v 1.0.1 2003/03/17 22:14:34 acassen Exp $
+ * Version:     $Id: check_http.h,v 1.0.2 2003/04/14 02:35:12 acassen Exp $
  *
  * Authors:     Alexandre Cassen, <acassen@linux-vs.org>
  *              Jan Holmberg, <jan@artech.net>
index de9cd70..84c8c43 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Part:        check_tcp.c include file.
  *
- * Version:     $Id: check_tcp.h,v 1.0.1 2003/03/17 22:14:34 acassen Exp $
+ * Version:     $Id: check_tcp.h,v 1.0.2 2003/04/14 02:35:12 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
index 92b2b79..64bea1d 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Part:        Daemon process handling.
  *
- * Version:     $Id: daemon.h,v 1.0.1 2003/03/17 22:14:34 acassen Exp $
+ * Version:     $Id: daemon.h,v 1.0.2 2003/04/14 02:35:12 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
index faa5dfe..205fbe4 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Part:        Dynamic data structure definition.
  *
- * Version:     $Id: data.h,v 1.0.1 2003/03/17 22:14:34 acassen Exp $
+ * Version:     $Id: data.h,v 1.0.2 2003/04/14 02:35:12 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
@@ -78,11 +78,29 @@ typedef struct _real_server {
        int alive;
 } real_server;
 
+/* Virtual Server group definition */
+typedef struct _virtual_server_group_entry {
+       uint32_t addr_ip;
+       uint8_t range;
+       uint32_t vfwmark;
+       uint16_t addr_port;
+       int alive;
+       int rsalive;
+} virtual_server_group_entry;
+
+typedef struct _virtual_server_group {
+       char *gname;
+       list addr_ip;
+       list range;
+       list vfwmark;
+} virtual_server_group;
+
 /* Virtual Server definition */
 typedef struct _virtual_server {
+       char *vsgname;
        uint32_t addr_ip;
-       uint32_t vfwmark;
        uint16_t addr_port;
+       uint32_t vfwmark;
        uint16_t service_type;
        int delay_loop;
        int ha_suspend;
@@ -113,6 +131,7 @@ typedef struct _data {
        list static_routes;
        list vrrp_sync_group;
        list vrrp;
+       list vs_group;
        list vs;
 } data;
 
@@ -120,10 +139,31 @@ typedef struct _data {
 #define ISALIVE(S)     ((S)->alive)
 #define SET_ALIVE(S)   ((S)->alive = 1)
 #define UNSET_ALIVE(S) ((S)->alive = 0)
+#define SET_RSALIVE(S) ((S)->rsalive = 1)
+#define UNSET_RSALIVE(S)((S)->rsalive = 0)
 #define SVR_IP(H)      ((H)->addr_ip)
 #define SVR_PORT(H)    ((H)->addr_port)
 #define VHOST(V)       ((V)->virtualhost)
-#define LAST_RS_TYPE(V)        ((V)->last_rs_type)
+
+#define VS_ISEQ(X,Y)   ((X)->addr_ip                 == (Y)->addr_ip &&                \
+                        (X)->addr_port               == (Y)->addr_port &&              \
+                        (X)->vfwmark                 == (Y)->vfwmark &&                \
+                        (X)->service_type            == (Y)->service_type &&           \
+                        (X)->loadbalancing_kind      == (Y)->loadbalancing_kind &&     \
+                        (X)->nat_mask                == (Y)->nat_mask &&               \
+                        (X)->granularity_persistence == (Y)->granularity_persistence &&\
+                        !strcmp((X)->sched, (Y)->sched) &&                             \
+                        !strcmp((X)->timeout_persistence, (Y)->timeout_persistence) && \
+                        !strcmp((X)->vsgname, (Y)->vsgname))
+
+#define VSGE_ISEQ(X,Y) ((X)->addr_ip   == (Y)->addr_ip &&      \
+                        (X)->range     == (Y)->range &&        \
+                        (X)->vfwmark   == (Y)->vfwmark &&      \
+                        (X)->addr_port == (Y)->addr_port)
+
+#define RS_ISEQ(X,Y)   ((X)->addr_ip   == (Y)->addr_ip &&      \
+                        (X)->addr_port == (Y)->addr_port &&    \
+                        (X)->weight    == (Y)->weight)
 
 /* prototypes */
 extern void alloc_email(char *addr);
@@ -135,6 +175,8 @@ extern void alloc_vrrp(char *iname);
 extern void alloc_vrrp_vip(vector strvec);
 extern void alloc_vrrp_evip(vector strvec);
 extern void alloc_vrrp_vroute(vector strvec);
+extern void alloc_vsg(char *gname);
+extern void alloc_vsg_entry(vector strvec);
 extern void alloc_vs(char *ip, char *port);
 extern void alloc_rs(char *ip, char *port);
 extern void alloc_ssvr(char *ip, char *port);
index 6ccd0b1..655eff9 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Part:        ipfwwrapper.c include file.
  *
- * Version:     $Id: ipfwwrapper.h,v 1.0.1 2003/03/17 22:14:34 acassen Exp $
+ * Version:     $Id: ipfwwrapper.h,v 1.0.2 2003/04/14 02:35:12 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
index 3453505..86054e1 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Part:        ipvswrapper.c include file.
  *
- * Version:     $Id: ipvswrapper.h,v 1.0.1 2003/03/17 22:14:34 acassen Exp $
+ * Version:     $Id: ipvswrapper.h,v 1.0.2 2003/04/14 02:35:12 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
 
 extern thread_master *master;
 
+/* Macro */
+#define IPVS_ALIVE(X,Y)        (((X) == IP_VS_SO_SET_ADD && !(Y)->alive)       || \
+                        ((X) == IP_VS_SO_SET_DEL && (Y)->alive)        || \
+                        ((X) == IP_VS_SO_SET_ADDDEST && !(Y)->rsalive) || \
+                        ((X) == IP_VS_SO_SET_DELDEST && (Y)->rsalive)  || \
+                        (X) == IP_VS_SO_SET_EDITDEST                      \
+                       )
+
 /* prototypes */
-extern int ipvs_cmd(int cmd, virtual_server * vserver, real_server * rserver);
+extern virtual_server_group *ipvs_get_group_by_name(char *gname, list l);
+extern int ipvs_group_remove_entry(virtual_server *vs,
+                                  virtual_server_group_entry *vsge);
+extern int ipvs_cmd(int cmd, list vs_group, virtual_server * vserver, real_server * rserver);
 extern int ipvs_syncd_cmd(int cmd, char *ifname, int state);
 extern void ipvs_syncd_master(char *ifname);
 extern void ipvs_syncd_backup(char *ifname);
index 9541818..5070baf 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Part:        ipwrapper.c include file.
  *
- * Version:     $Id: ipwrapper.h,v 1.0.1 2003/03/17 22:14:34 acassen Exp $
+ * Version:     $Id: ipwrapper.h,v 1.0.2 2003/04/14 02:35:12 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
@@ -62,7 +62,7 @@ extern int init_services(void);
 extern int clear_services(void);
 extern int clear_diff_services(void);
 
-extern int ipvs_cmd(int cmd, virtual_server * vserver, real_server * rserver);
+//extern int ipvs_cmd(int cmd, virtual_server * vserver, real_server * rserver);
 extern int ipfw_cmd(int cmd, virtual_server * vserver, real_server * rserver);
 
 #endif
index f13f0ee..922e268 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Part:        layer4.c include file.
  *
- * Version:     $Id: layer4.h,v 1.0.1 2003/03/17 22:14:34 acassen Exp $
+ * Version:     $Id: layer4.h,v 1.0.2 2003/04/14 02:35:12 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
index d37456c..82076bd 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Part:        Main program include file.
  *
- * Version:     $Id: main.h,v 1.0.1 2003/03/17 22:14:34 acassen Exp $
+ * Version:     $Id: main.h,v 1.0.2 2003/04/14 02:35:12 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
@@ -65,8 +65,8 @@ extern void register_vrrp_thread(void);
 /* Build version */
 #define PROG    "Keepalived"
 
-#define VERSION_CODE 0x010001
-#define DATE_CODE    0x110303
+#define VERSION_CODE 0x010002
+#define DATE_CODE    0x0E0403
 
 #define KEEPALIVED_VERSION(version)    \
        (version >> 16) & 0xFF,         \
index b9b45c8..979c38b 100644 (file)
@@ -5,7 +5,7 @@
  * 
  * Part:        cfreader.c include file.
  *  
- * Version:     $Id: parser.h,v 1.0.1 2003/03/17 22:14:34 acassen Exp $
+ * Version:     $Id: parser.h,v 1.0.2 2003/04/14 02:35:12 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
index f9602a5..de6ec0f 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Part:        pidfile.c include file.
  *
- * Version:     $Id: pidfile.h,v 1.0.1 2003/03/17 22:14:34 acassen Exp $
+ * Version:     $Id: pidfile.h,v 1.0.2 2003/04/14 02:35:12 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
index 3cb73bf..ad468d0 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Part:        smtp.c include file.
  *
- * Version:     $Id: smtp.h,v 1.0.1 2003/03/17 22:14:34 acassen Exp $
+ * Version:     $Id: smtp.h,v 1.0.2 2003/04/14 02:35:12 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
index d7bf971..a57e3c5 100644 (file)
@@ -6,7 +6,7 @@
  *
  * Part:        vrrp.c program include file.
  *
- * Version:     $Id: vrrp.h,v 1.0.1 2003/03/17 22:14:34 acassen Exp $
+ * Version:     $Id: vrrp.h,v 1.0.2 2003/04/14 02:35:12 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
index d5fe603..c600ce2 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Part:        vrrp_arp.c include file.
  *
- * Version:     $Id: vrrp_arp.h,v 1.0.1 2003/03/17 22:14:34 acassen Exp $
+ * Version:     $Id: vrrp_arp.h,v 1.0.2 2003/04/14 02:35:12 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
index f7bc6af..e54f6dd 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Part:        vrrp_if.c include file.
  *
- * Version:     $Id: vrrp_if.h,v 1.0.1 2003/03/17 22:14:34 acassen Exp $
+ * Version:     $Id: vrrp_if.h,v 1.0.2 2003/04/14 02:35:12 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
index 41f0436..2b65283 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Part:        vrrp_ipaddress.c include file.
  *
- * Version:     $Id: vrrp_ipaddress.h,v 1.0.1 2003/03/17 22:14:34 acassen Exp $
+ * Version:     $Id: vrrp_ipaddress.h,v 1.0.2 2003/04/14 02:35:12 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
index 9a34957..4927279 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Part:        vrrp_iproute.c include file.
  *
- * Version:     $Id: vrrp_iproute.h,v 1.0.1 2003/03/17 22:14:34 acassen Exp $
+ * Version:     $Id: vrrp_iproute.h,v 1.0.2 2003/04/14 02:35:12 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
 
 /* types definition */
 typedef struct _ip_route {
-       uint32_t dst;    /* RTA_DST */
+       uint32_t dst;   /* RTA_DST */
        uint8_t dmask;
-       uint32_t gw;     /* RTA_GATEWAY */
-       int index;       /* RTA_OIF */
+       uint32_t gw;    /* RTA_GATEWAY */
+       uint32_t src;   /* RTA_PREFSRC */
+       int index;      /* RTA_OIF */
+       int table;
        int set;
 } ip_route;
 
@@ -48,6 +50,8 @@ typedef struct _ip_route {
 #define ROUTE_ISEQ(X,Y)        ((X)->dst    == (Y)->dst   && \
                         (X)->dmask  == (Y)->dmask && \
                         (X)->gw     == (Y)->gw    && \
+                        (X)->src    == (Y)->src   && \
+                        (X)->table  == (Y)->table && \
                         (X)->index  == (Y)->index)
 
 /* prototypes */
index b260495..da82b8f 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Part:        vrrp_ipsecah.c include file.
  * 
- * Version:     $Id: vrrp_ipsecah.h,v 1.0.1 2003/03/17 22:14:34 acassen Exp $
+ * Version:     $Id: vrrp_ipsecah.h,v 1.0.2 2003/04/14 02:35:12 acassen Exp $
  * 
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *              
index 5b1411a..5dbdfe8 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Part:        vrrp_netlink.c include file.
  *
- * Version:     $Id: vrrp_netlink.h,v 1.0.1 2003/03/17 22:14:34 acassen Exp $
+ * Version:     $Id: vrrp_netlink.h,v 1.0.2 2003/04/14 02:35:12 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
index cb802ca..d928af9 100644 (file)
@@ -6,7 +6,7 @@
  *
  * Part:        vrrp_notify.c include file.
  *
- * Version:     $Id: vrrp_notify.h,v 1.0.1 2003/03/17 22:14:34 acassen Exp $
+ * Version:     $Id: vrrp_notify.h,v 1.0.2 2003/04/14 02:35:12 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
index beea4d1..9ec2625 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Part:        vrrp_scheduler.c include file.
  * 
- * Version:     $Id: vrrp_scheduler.h,v 1.0.1 2003/03/17 22:14:34 acassen Exp $
+ * Version:     $Id: vrrp_scheduler.h,v 1.0.2 2003/04/14 02:35:12 acassen Exp $
  * 
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *              
index 2b4ee05..04bf766 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Part:        vrrp_sync.c include file.
  * 
- * Version:     $Id: vrrp_sync.h,v 1.0.1 2003/03/17 22:14:34 acassen Exp $
+ * Version:     $Id: vrrp_sync.h,v 1.0.2 2003/04/14 02:35:12 acassen Exp $
  * 
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *              
index ddfc287..16b2b36 100644 (file)
@@ -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 1.0.1 2003/03/17 22:14:34 acassen Exp $
+ * Version:     $Id: vrrp.c,v 1.0.2 2003/04/14 02:35:12 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
@@ -932,15 +932,15 @@ open_vrrp_socket(const int proto, const int index)
        if (!IF_ISUP(ifp))
                return fd;
 
-        /* open the socket */
-        fd = socket(AF_INET, SOCK_RAW, proto);
-        if (fd < 0) {
-                int err = errno;
-                syslog(LOG_INFO,
-                       "cant open raw socket. errno=%d. (try to run it as root)",
-                       err);
-                return -1;
-        }
+       /* open the socket */
+       fd = socket(AF_INET, SOCK_RAW, proto);
+       if (fd < 0) {
+               int err = errno;
+               syslog(LOG_INFO,
+                      "cant open raw socket. errno=%d. (try to run it as root)",
+                      err);
+               return -1;
+       }
 
        /* Join the VRRP MCAST group */
        if_join_vrrp_group(fd, ifp, proto);
index 0ea2ce1..4d50c2a 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Part:        ARP primitives.
  *
- * Version:     $Id: vrrp_arp.c,v 1.0.1 2003/03/17 22:14:34 acassen Exp $
+ * Version:     $Id: vrrp_arp.c,v 1.0.2 2003/04/14 02:35:12 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
index 5868ebe..259732b 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Part:        Interfaces manipulation.
  *
- * Version:     $Id: vrrp_if.c,v 1.0.1 2003/03/17 22:14:34 acassen Exp $
+ * Version:     $Id: vrrp_if.c,v 1.0.2 2003/04/14 02:35:12 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
index c4eb932..d29abc3 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Part:        NETLINK IPv4 address manipulation.
  *
- * Version:     $Id: vrrp_ipaddress.c,v 1.0.1 2003/03/17 22:14:34 acassen Exp $
+ * Version:     $Id: vrrp_ipaddress.c,v 1.0.2 2003/04/14 02:35:12 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
index 545a063..06a2d56 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Part:        NETLINK IPv4 routes manipulation.
  *
- * Version:     $Id: vrrp_iproute.c,v 1.0.1 2003/03/17 22:14:34 acassen Exp $
+ * Version:     $Id: vrrp_iproute.c,v 1.0.2 2003/04/14 02:35:12 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
@@ -46,12 +46,12 @@ netlink_route_ipv4(ip_route *iproute, int cmd)
 
        memset(&req, 0, sizeof (req));
 
-       req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg));
+       req.n.nlmsg_len   = NLMSG_LENGTH(sizeof(struct rtmsg));
        req.n.nlmsg_flags = NLM_F_REQUEST | NLM_F_CREATE;
-       req.n.nlmsg_type = cmd ? RTM_NEWROUTE : RTM_DELROUTE;
-       req.r.rtm_family = AF_INET;
-       req.r.rtm_table = RT_TABLE_MAIN;
-       req.r.rtm_scope = RT_SCOPE_NOWHERE;
+       req.n.nlmsg_type  = cmd ? RTM_NEWROUTE : RTM_DELROUTE;
+       req.r.rtm_family  = AF_INET;
+       req.r.rtm_table   = iproute->table ? iproute->table : RT_TABLE_MAIN;
+       req.r.rtm_scope   = RT_SCOPE_NOWHERE;
 
        if (cmd) {
                req.r.rtm_protocol = RTPROT_BOOT;
@@ -60,12 +60,15 @@ netlink_route_ipv4(ip_route *iproute, int cmd)
        }
 
        /* Set routing entry */
+       req.r.rtm_dst_len = iproute->dmask;
        addattr_l(&req.n, sizeof(req), RTA_DST,         &iproute->dst, 4);
        addattr_l(&req.n, sizeof(req), RTA_GATEWAY,     &iproute->gw,  4);
        if (iproute->index)
                addattr32(&req.n, sizeof(req), RTA_OIF, iproute->index);
-       req.r.rtm_dst_len = iproute->dmask;
+       if (iproute->src)
+               addattr_l(&req.n, sizeof(req), RTA_PREFSRC, &iproute->src, 4);
 
+       /* Send to netlink channel */
        if (netlink_socket(&nlh, 0) < 0)
                return -1;
 
@@ -111,32 +114,32 @@ dump_route(void *data)
 {
        ip_route *route = data;
        char *log_msg = MALLOC(100);
-       char *to_msg = NULL;
-       char *gw_msg = NULL;
-       char *dev_msg = NULL;
+       char *tmp = MALLOC(30);
 
        if (route->dst) {
-               to_msg = MALLOC(30);
-               snprintf(to_msg, 30, "%s/%d",
-                        inet_ntop2(route->dst), route->dmask);
-               strncat(log_msg, to_msg, 30);
-               FREE(to_msg);
+               snprintf(tmp, 30, "%s/%d", inet_ntop2(route->dst), route->dmask);
+               strncat(log_msg, tmp, 30);
        }
        if (route->gw) {
-               gw_msg = MALLOC(30);
-               snprintf(gw_msg, 30, " gw %s", inet_ntop2(route->gw));
-               strncat(log_msg, gw_msg, 30);
-               FREE(gw_msg);
+               snprintf(tmp, 30, " gw %s", inet_ntop2(route->gw));
+               strncat(log_msg, tmp, 30);
+       }
+       if (route->src) {
+               snprintf(tmp, 30, " src %s", inet_ntop2(route->src));
+               strncat(log_msg, tmp, 30);
        }
        if (route->index) {
-               dev_msg = MALLOC(30);
-               snprintf(dev_msg, 30, " dev %s",
-                        IF_NAME(if_get_by_ifindex(route->index)));
-               strncat(log_msg, dev_msg, 30);
-               FREE(dev_msg);
+               snprintf(tmp, 30, " dev %s", IF_NAME(if_get_by_ifindex(route->index)));
+               strncat(log_msg, tmp, 30);
+       }
+       if (route->table) {
+               snprintf(tmp, 30, " table %d", route->table);
+               strncat(log_msg, tmp, 30);
        }
 
        syslog(LOG_INFO, "     %s", log_msg);
+
+       FREE(tmp);
        FREE(log_msg);
 }
 void
@@ -156,8 +159,12 @@ alloc_route(list rt_list, vector strvec)
                /* cmd parsing */
                if (!strcmp(str, "via") || !strcmp(str, "gw")) {
                        inet_ston(VECTOR_SLOT(strvec, ++i), &new->gw);
+               } else if (!strcmp(str, "src")) {
+                       inet_ston(VECTOR_SLOT(strvec, ++i), &new->src);
                } else if (!strcmp(str, "dev") || !strcmp(str, "oif")) {
                        new->index = IF_INDEX(if_get_by_ifname(VECTOR_SLOT(strvec, ++i)));
+               } else if (!strcmp(str, "table")) {
+                       new->table = atoi(VECTOR_SLOT(strvec, ++i));
                } else {
                        if (!strcmp(str, "to")) i++;
                        if (inet_ston(VECTOR_SLOT(strvec, i), &ipaddr)) {
index f3513fd..8cf4e1e 100644 (file)
@@ -7,7 +7,7 @@
  *              authentication data encryption using HMAC MD5 according to
  *              RFCs 2085 & 2104.
  *
- * Version:     $Id: vrrp_ipsecah.c,v 1.0.1 2003/03/17 22:14:34 acassen Exp $
+ * Version:     $Id: vrrp_ipsecah.c,v 1.0.2 2003/04/14 02:35:12 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
index 729df53..f16333b 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Part:        NETLINK kernel command channel.
  *
- * Version:     $Id: vrrp_netlink.c,v 1.0.1 2003/03/17 22:14:34 acassen Exp $
+ * Version:     $Id: vrrp_netlink.c,v 1.0.2 2003/04/14 02:35:12 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
index 384eafc..34b77e6 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Part:        VRRP state transition notification scripts handling.
  *
- * Version:     $Id: vrrp_notify.c,v 1.0.1 2003/03/17 22:14:34 acassen Exp $
+ * Version:     $Id: vrrp_notify.c,v 1.0.2 2003/04/14 02:35:12 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
index fe656b2..f7eeadf 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Part:        Sheduling framework for vrrp code.
  *
- * Version:     $Id: vrrp_scheduler.c,v 1.0.1 2003/03/17 22:14:34 acassen Exp $
+ * Version:     $Id: vrrp_scheduler.c,v 1.0.2 2003/04/14 02:35:12 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
index 33a309e..7f682e8 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Part:        VRRP synchronization framework.
  *
- * Version:     $Id: vrrp_sync.c,v 1.0.1 2003/03/17 22:14:34 acassen Exp $
+ * Version:     $Id: vrrp_sync.c,v 1.0.2 2003/04/14 02:35:12 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
index 6857c0a..9546014 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Part:        HTML stream parser utility functions.
  *
- * Version:     $Id: html.c,v 1.0.1 2003/03/17 22:14:34 acassen Exp $
+ * Version:     $Id: html.c,v 1.0.2 2003/04/14 02:35:12 acassen Exp $
  *
  * Authors:     Alexandre Cassen, <acassen@linux-vs.org>
  *
index 65c8ac7..9923d99 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Part:        parser.c include file.
  *
- * Version:     $Id: html.h,v 1.0.1 2003/03/17 22:14:34 acassen Exp $
+ * Version:     $Id: html.h,v 1.0.2 2003/04/14 02:35:12 acassen Exp $
  *
  * Authors:     Alexandre Cassen, <acassen@linux-vs.org>
  *
index 23e3d42..217030d 100644 (file)
@@ -5,7 +5,7 @@
  * 
  * Part:        List structure manipulation.
  *  
- * Version:     $Id: list.c,v 1.0.1 2003/03/17 22:14:34 acassen Exp $
+ * Version:     $Id: list.c,v 1.0.2 2003/04/14 02:35:12 acassen Exp $
  * 
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *              
index e3b7f31..e902749 100644 (file)
@@ -5,7 +5,7 @@
  * 
  * Part:        list.c include file.
  *  
- * Version:     $Id: list.h,v 1.0.1 2003/03/17 22:14:34 acassen Exp $
+ * Version:     $Id: list.h,v 1.0.2 2003/04/14 02:35:12 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
index faba074..6a1af0d 100644 (file)
@@ -6,7 +6,7 @@
  * Part:        Memory management framework. This framework is used to
  *              find any memory leak.
  *
- * Version:     $Id: memory.c,v 1.0.1 2003/03/17 22:14:34 acassen Exp $
+ * Version:     $Id: memory.c,v 1.0.2 2003/04/14 02:35:12 acassen Exp $
  *
  * Authors:     Alexandre Cassen, <acassen@linux-vs.org>
  *              Jan Holmberg, <jan@artech.net>
index 8d509e8..c1e4ff5 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Part:        memory.c include file.
  *
- * Version:     $Id: memory.h,v 1.0.1 2003/03/17 22:14:34 acassen Exp $
+ * Version:     $Id: memory.h,v 1.0.2 2003/04/14 02:35:12 acassen Exp $
  *
  * Authors:     Alexandre Cassen, <acassen@linux-vs.org>
  *              Jan Holmberg, <jan@artech.net>
index 9e2332a..0ee68c9 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Part:        Forked system call to launch an extra script.
  *
- * Version:     $Id: notify.c,v 1.0.1 2003/03/17 22:14:34 acassen Exp $
+ * Version:     $Id: notify.c,v 1.0.2 2003/04/14 02:35:12 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
index a461f42..e2787e7 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Part:        notify.c include file.
  *
- * Version:     $Id: notify.h,v 1.0.1 2003/03/17 22:14:34 acassen Exp $
+ * Version:     $Id: notify.h,v 1.0.2 2003/04/14 02:35:12 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
index 478179c..edcebf5 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 1.0.1 2003/03/17 22:14:34 acassen Exp $
+ * Version:     $Id: scheduler.c,v 1.0.2 2003/04/14 02:35:12 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
index 301d6f5..b1190da 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Part:        scheduler.c include file.
  *
- * Version:     $Id: scheduler.h,v 1.0.1 2003/03/17 22:14:34 acassen Exp $
+ * Version:     $Id: scheduler.h,v 1.0.2 2003/04/14 02:35:12 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
index a0d9fba..b406a59 100644 (file)
@@ -5,7 +5,7 @@
  * 
  * Part:        Timer manipulations.
  *  
- * Version:     $Id: timer.c,v 1.0.1 2003/03/17 22:14:34 acassen Exp $
+ * Version:     $Id: timer.c,v 1.0.2 2003/04/14 02:35:12 acassen Exp $
  * 
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *              
index d2a4335..666ee48 100644 (file)
@@ -5,7 +5,7 @@
  * 
  * Part:        timer.c include file.
  *  
- * Version:     $Id: timer.h,v 1.0.1 2003/03/17 22:14:34 acassen Exp $
+ * Version:     $Id: timer.h,v 1.0.2 2003/04/14 02:35:12 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
index 26dbf87..b3607bf 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Part:        General program utils.
  *
- * Version:     $Id: utils.c,v 1.0.1 2003/03/17 22:14:34 acassen Exp $
+ * Version:     $Id: utils.c,v 1.0.2 2003/04/14 02:35:12 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
@@ -91,7 +91,7 @@ inet_ntoa2(uint32_t ip, char *buf)
        return buf;
 }
 
-/* IP string to network mask representation */
+/* IP string to network mask representation. CIDR notation. */
 uint8_t
 inet_stom(char *addr)
 {
@@ -107,6 +107,22 @@ inet_stom(char *addr)
        return mask;
 }
 
+/* IP string to network range representation. */
+uint8_t
+inet_stor(char *addr)
+{
+       uint8_t range = 0;
+       char *cp = addr;
+
+       if (!strstr(addr, "-"))
+               return range;
+       while (*cp != '-' && *cp != '\0')
+               cp++;
+       if (*cp == '-')
+               return atoi(++cp);
+       return range;
+}
+
 /*
  * IP string to network representation
  * Highly inspired from Paul Vixie code.
@@ -122,7 +138,7 @@ inet_ston(const char *addr, uint32_t * dst)
        octets = 0;
        *(tp = tmp) = 0;
 
-       while ((ch = *addr++) != '\0' && ch != '/') {
+       while ((ch = *addr++) != '\0' && ch != '/' && ch != '-') {
                const char *pch;
                if ((pch = strchr(digits, ch)) != NULL) {
                        u_int new = *tp * 10 + (pch - digits);
index 93693c9..0b9ab84 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Part:        utils.h include file.
  *
- * Version:     $Id: utils.h,v 1.0.1 2003/03/17 22:14:34 acassen Exp $
+ * Version:     $Id: utils.h,v 1.0.2 2003/04/14 02:35:12 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
@@ -46,6 +46,7 @@ extern void print_buffer(int count, char *buff);
 extern char *inet_ntop2(uint32_t ip);
 extern char *inet_ntoa2(uint32_t ip, char *buf);
 extern uint8_t inet_stom(char *addr);
+extern uint8_t inet_stor(char *addr);
 extern int inet_ston(const char *addr, uint32_t * dst);
 extern char *get_local_name(void);
 
index 766914b..9a85bc3 100644 (file)
@@ -5,7 +5,7 @@
  * 
  * Part:        Vector structure manipulation.
  *  
- * Version:     $Id: vector.c,v 1.0.1 2003/03/17 22:14:34 acassen Exp $
+ * Version:     $Id: vector.c,v 1.0.2 2003/04/14 02:35:12 acassen Exp $
  * 
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *              
index fec7bd8..eb6b94d 100644 (file)
@@ -5,7 +5,7 @@
  * 
  * Part:        vector.c include file.
  *  
- * Version:     $Id: vector.h,v 1.0.1 2003/03/17 22:14:34 acassen Exp $
+ * Version:     $Id: vector.h,v 1.0.2 2003/04/14 02:35:12 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *