* 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.
-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>
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
...
}
...
}
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)
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
}
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
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
--- /dev/null
+! 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
+ }
+ }
+}
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
*
* 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>
*
*
* 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>
*
}
#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))
{
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))
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);
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;
}
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);
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();
* 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>
*
*
* 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>
*
}
/*
- * 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 */
* 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>
*
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)
{
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 */
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));
#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);
*
* 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>
*
* 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>
*
*
* 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>
*
*
* 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>
*
* 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>
* 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>
* 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>
*
* 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>
*
* 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>
*
* 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);
}
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;
}
-
-
#else /* KERNEL 2.4 LVS handling */
static int
#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;
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;
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;
*
* 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>
*
*/
#include "ipwrapper.h"
+#include "ipvswrapper.h"
#include "utils.h"
#include "notify.h"
/* 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.
/* 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;
}
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)
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)
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
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;
}
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);
"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
(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);
}
(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);
}
"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);
}
}
-/* 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 */
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;
}
}
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
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;
}
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)
, 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;
}
}
* 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 */
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;
}
}
*
* 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>
*
*
* 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>
*
* 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>
*
* 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>
*
* 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>
*
* 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>
*
*
* 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>
*
*
* 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>
*
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;
list static_routes;
list vrrp_sync_group;
list vrrp;
+ list vs_group;
list vs;
} 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);
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);
*
* 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>
*
*
* 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);
*
* 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>
*
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
*
* 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>
*
*
* 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>
*
/* 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, \
*
* 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>
*
*
* 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>
*
*
* 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>
*
*
* 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>
*
*
* 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>
*
*
* 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>
*
*
* 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>
*
*
* 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;
#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 */
*
* 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>
*
*
* 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>
*
*
* 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>
*
*
* 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>
*
*
* 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>
*
* 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>
*
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);
*
* 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>
*
*
* 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>
*
*
* 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>
*
*
* 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>
*
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;
}
/* 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;
{
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
/* 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)) {
* 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>
*
*
* 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>
*
*
* 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>
*
*
* 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>
*
*
* 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>
*
*
* 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>
*
*
* 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>
*
*
* 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>
*
*
* 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>
*
* 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>
*
* 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>
*
* 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>
*
*
* 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>
*
* 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>
*
*
* 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>
*
*
* 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>
*
*
* 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>
*
*
* 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>
*
return buf;
}
-/* IP string to network mask representation */
+/* IP string to network mask representation. CIDR notation. */
uint8_t
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.
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);
*
* 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>
*
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);
*
* 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>
*
*
* 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>
*