* keepalived-0.5.9 released.
* Added support to realserver_group. The work is not yet finished since
it introduces new compilation design currently not supported. So please
do not use yet.
* VRRP : Review the script notification. Moved to a script per VRRP
instance state => Created new keywords notify_backup|master|fault
to run a specific script during backup|master|fault state transition.
* VRRP : Added support to quoted strings for notify_backup|master|fault.
Can now launch script passing arguments.
See sample directory for examples.
* VRRP : Added a protocol extension called "virtual_ipaddress_excluded".
This configuration block is similar to "virtual_ipaddress" block =>
those VIPs (called E-VIPs) are set throught netlink kernel channel and
gratuitous arp are sent over each E-VIP. The only difference is that
they are not added into VRRP packet adverts. This can be usefull for
big env where you want to run many VRRP VIPs (200 for example).
VRRP packet lenght are limited to a 20 VIPs, if you want more VRRP VIPs
add them to the "virtual_ipaddress_excluded" configuration block.
* VRRP : Added more logging facility when setting/removings VIPs & E-VIPs.
* VRRP : Created a new FSM state called become_master in charge of
VIPs/E-VIPs/notifications handling. The goto_master state is now a state
where the instance send an advert to force a new MASTER election setting
the instance into a transition mode. If election success its finaly
transit to become_master state to own VIPs/E-VIPs and launch scripts.
* VRRP : Force a new MASTER election when receiving a lower prio advert.
* VRRP : Review the vrrp_scheduler.c to use more conventional FSM design.
This reduce and beautifull the code.
* VRRP : Fixed a very noisy flapping issue observed on heavy loaded env.
Simulating big traffic on a backbone figure out this flapping issue.
Added support to a TIMER_MICRO_ADJUST to prevent against timer degradation.
This can be view as a DOS protection policy. VRRP MASTER timers are adjusted
if they are too degradated, due to heavy loaded networking env introducing
latency receiving/sending VRRP protocol adverts.
Thanks goes to Paul, <xerox@foonet.net> for pointing it out and providing
access to its Internet routing backbone.
Thanks to Richard L. Allbery, <rla@prideindustries.com> for suggection.
+++ /dev/null
-/*
- * Soft: Keepalived is a failover program for the LVS project
- * <www.linuxvirtualserver.org>. It monitor & manipulate
- * a loadbalanced server pool using multi-layer checks.
- *
- * Part: Dynamic data structure definition.
- *
- * Version: $Id: data.c,v 0.5.8 2002/05/21 16:09:46 acassen Exp $
- *
- * Author: Alexandre Cassen, <acassen@linux-vs.org>
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- * See the GNU General Public License for more details.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
- */
-
-#include "data.h"
-#include "memory.h"
-#include "utils.h"
-#include "check_api.h"
-#include "vrrp.h"
-
-extern data *conf_data;
-
-/* email facility functions */
-static void free_email(void *data)
-{
- FREE(data);
-}
-static void dump_email(void *data)
-{
- char *addr = data;
- syslog(LOG_INFO, " Email notification = %s", addr);
-}
-void alloc_email(char *addr)
-{
- int size = strlen(addr);
- char *new;
-
- new = (char *)MALLOC(size+1);
- memcpy(new, addr, size);
-
- list_add(conf_data->email, new);
-}
-
-/* SSL facility functions */
-SSL_DATA *alloc_ssl(void)
-{
- SSL_DATA *ssl = (SSL_DATA *)MALLOC(sizeof(SSL_DATA));
- return ssl;
-}
-static void free_ssl(void)
-{
- SSL_DATA *ssl = conf_data->ssl;
-
- if (!ssl) return;
- FREE_PTR(ssl->password);
- FREE_PTR(ssl->cafile);
- FREE_PTR(ssl->certfile);
- FREE_PTR(ssl->keyfile);
- FREE(ssl);
-}
-static void dump_ssl(void)
-{
- SSL_DATA *ssl = conf_data->ssl;
-
- if (ssl->password)
- syslog(LOG_INFO, " Password : %s", ssl->password);
- if (ssl->cafile)
- syslog(LOG_INFO, " CA-file : %s", ssl->cafile);
- if (ssl->certfile)
- syslog(LOG_INFO, " Certificate file : %s", ssl->certfile);
- if (ssl->keyfile)
- syslog(LOG_INFO, " Key file : %s", ssl->keyfile);
- if (!ssl->password && !ssl->cafile && !ssl->certfile && !ssl->keyfile)
- syslog(LOG_INFO, " Using autogen SSL context");
-}
-
-/* VRRP facility functions */
-static void free_vrrp(void *data)
-{
- vrrp_rt *vrrp = data;
-
- FREE(vrrp->iname);
- FREE_PTR(vrrp->isync);
- FREE_PTR(vrrp->lvs_syncd_if);
- FREE_PTR(vrrp->vaddr);
- FREE(vrrp->ipsecah_counter);
- FREE(vrrp);
-}
-static void dump_vrrp(void *data)
-{
- vrrp_rt *vrrp = data;
- int i;
-
- syslog(LOG_INFO, " VRRP Instance = %s", vrrp->iname);
- if (vrrp->isync)
- syslog(LOG_INFO, " Sync with instance = %s", vrrp->isync);
- if (vrrp->init_state == VRRP_STATE_BACK)
- syslog(LOG_INFO, " Want State = BACKUP");
- else
- syslog(LOG_INFO, " Want State = MASTER");
- syslog(LOG_INFO, " Runing on device = %s", IF_NAME(vrrp->ifp));
- if (vrrp->lvs_syncd_if)
- syslog(LOG_INFO, " Runing LVS sync daemon on interface = %s"
- , vrrp->lvs_syncd_if);
- syslog(LOG_INFO, " Virtual Router ID = %d", vrrp->vrid);
- syslog(LOG_INFO, " Priority = %d", vrrp->priority);
- syslog(LOG_INFO, " Advert interval = %dsec", vrrp->adver_int/TIMER_HZ);
- if (vrrp->preempt)
- syslog(LOG_INFO, " Preempt Active");
- if (vrrp->auth_type) {
- syslog(LOG_INFO, " Authentication type = %s",
- (vrrp->auth_type == VRRP_AUTH_AH)?"IPSEC_AH":"SIMPLE_PASSWORD" );
- syslog(LOG_INFO, " Password = %s", vrrp->auth_data);
- }
- syslog(LOG_INFO, " VIP count = %d", vrrp->naddr);
- for (i = 0; i < vrrp->naddr; i++)
- syslog(LOG_INFO, " VIP%d = %s", i+1, ip_ntoa(vrrp->vaddr[i].addr));
- if (vrrp->notify_exec)
- syslog(LOG_INFO, " Using notification script = %s"
- , vrrp->notify_file);
- if (vrrp->smtp_alert)
- syslog(LOG_INFO, " Using smtp notification");
-}
-void alloc_vrrp(char *iname)
-{
- int size = strlen(iname);
- seq_counter *counter;
- vrrp_rt *new;
-
- /* Allocate new VRRP structure */
- new = (vrrp_rt *) MALLOC(sizeof(vrrp_rt));
- counter = (seq_counter *) MALLOC(sizeof(seq_counter));
-
- /* Build the structure */
- new->ipsecah_counter = counter;
-
- /* Set default values */
- new->wantstate = VRRP_STATE_BACK;
- new->init_state = VRRP_STATE_BACK;
- new->adver_int = TIMER_HZ;
- new->iname = (char *)MALLOC(size+1);
- memcpy(new->iname, iname, size);
-
- list_add(conf_data->vrrp, new);
-}
-void alloc_vrrp_vip(char *vip)
-{
- vrrp_rt *vrrp = LIST_TAIL_DATA(conf_data->vrrp);
- uint32_t ipaddr = inet_addr(vip);
-
- vrrp->naddr++;
- if (vrrp->vaddr)
- vrrp->vaddr = REALLOC(vrrp->vaddr, vrrp->naddr*sizeof(*vrrp->vaddr));
- else
- vrrp->vaddr = (vip_addr *)MALLOC(sizeof(*vrrp->vaddr));
- vrrp->vaddr[vrrp->naddr-1].addr = ipaddr;
- vrrp->vaddr[vrrp->naddr-1].set = 0;
-}
-
-/* Virtual server facility functions */
-static void free_vs(void *data)
-{
- virtual_server *vs = data;
- FREE_PTR(vs->virtualhost);
- FREE_PTR(vs->s_svr);
- if (!LIST_ISEMPTY(vs->rs))
- free_list(vs->rs);
- FREE(vs);
-}
-static void dump_vs(void *data)
-{
- virtual_server *vs = data;
-
- if (vs->vfwmark)
- syslog(LOG_INFO, " VS FWMARK = %d", vs->vfwmark);
- else
- syslog(LOG_INFO, " VIP = %s, VPORT = %d"
- , ip_ntoa(SVR_IP(vs))
- , ntohs(SVR_PORT(vs)));
- if (vs->virtualhost)
- syslog(LOG_INFO, " VirtualHost = %s", vs->virtualhost);
- syslog(LOG_INFO, " delay_loop = %d, lb_algo = %s"
- , vs->delay_loop
- , vs->sched);
- if (atoi(vs->timeout_persistence) > 0)
- syslog(LOG_INFO, " persistence timeout = %s"
- , vs->timeout_persistence);
- if (vs->granularity_persistence)
- syslog(LOG_INFO, " persistence granularity = %s"
- , ip_ntoa(vs->granularity_persistence));
- syslog(LOG_INFO, " protocol = %s"
- , (vs->service_type == IPPROTO_TCP)?"TCP":"UDP");
-
- switch (vs->loadbalancing_kind) {
-#ifdef _WITH_LVS_
-#ifdef _KRNL_2_2_
- case 0:
- syslog(LOG_INFO, " lb_kind = NAT");
- syslog(LOG_INFO, " nat mask = %s", ip_ntoa(vs->nat_mask));
- break;
- case IP_MASQ_F_VS_DROUTE:
- syslog(LOG_INFO, " lb_kind = DR");
- break;
- case IP_MASQ_F_VS_TUNNEL:
- syslog(LOG_INFO, " lb_kind = TUN");
- break;
-#else
- case IP_VS_CONN_F_MASQ:
- syslog(LOG_INFO, " lb_kind = NAT");
- break;
- case IP_VS_CONN_F_DROUTE:
- syslog(LOG_INFO, " lb_kind = DR");
- break;
- case IP_VS_CONN_F_TUNNEL:
- syslog(LOG_INFO, " lb_kind = TUN");
- break;
-#endif
-#endif
- }
-
- if (vs->s_svr) {
- syslog(LOG_INFO, " sorry server = %s:%d"
- , ip_ntoa(SVR_IP(vs->s_svr))
- , ntohs(SVR_PORT(vs->s_svr)));
- }
- if (!LIST_ISEMPTY(vs->rs))
- dump_list(vs->rs);
-}
-void alloc_vs(char *ip, char *port)
-{
- virtual_server *new;
-
- new = (virtual_server *)MALLOC(sizeof(virtual_server));
-
- if (!strcmp(ip, "fwmark")) {
- new->vfwmark = atoi(port);
- } else {
- new->addr_ip = inet_addr(ip);
- new->addr_port = htons(atoi(port));
- }
- new->delay_loop = KEEPALIVED_DEFAULT_DELAY;
- strncpy(new->timeout_persistence, "0", 1);
- new->virtualhost = NULL;
-
- list_add(conf_data->vs, new);
-}
-
-/* Sorry server facility functions */
-void alloc_ssvr(char *ip, char *port)
-{
- virtual_server *vs = LIST_TAIL_DATA(conf_data->vs);
-
- vs->s_svr = (real_server *)MALLOC(sizeof(real_server));
- vs->s_svr->weight = 1;
- vs->s_svr->addr_ip = inet_addr(ip);
- vs->s_svr->addr_port = htons(atoi(port));
-}
-
-/* Real server facility functions */
-static void free_rs(void *data)
-{
- real_server *rs = data;
- FREE(rs);
-}
-static void dump_rs(void *data)
-{
- real_server *rs = data;
- syslog(LOG_INFO, " RIP = %s, RPORT = %d, WEIGHT = %d"
- , ip_ntoa(SVR_IP(rs))
- , ntohs(SVR_PORT(rs))
- , rs->weight);
-}
-void alloc_rs(char *ip, char *port)
-{
- virtual_server *vs = LIST_TAIL_DATA(conf_data->vs);
- real_server *new;
-
- new = (real_server *)MALLOC(sizeof(real_server));
-
- new->addr_ip = inet_addr(ip);
- new->addr_port = htons(atoi(port));
- new->alive = 1;
-
- if (LIST_ISEMPTY(vs->rs))
- vs->rs = alloc_list(free_rs, dump_rs);
- list_add(vs->rs, new);
- vs->last_rs_type = RS;
-}
-
-/* data facility functions */
-data *alloc_data(void)
-{
- data *new;
-
- new = (data *)MALLOC(sizeof(data));
- new->email = alloc_list(free_email, dump_email);
- new->vrrp = alloc_list(free_vrrp, dump_vrrp);
- new->vs = alloc_list(free_vs, dump_vs);
-
- return new;
-}
-void free_data(void)
-{
- free_ssl();
- free_list(conf_data->email);
- free_list(conf_data->vrrp);
- free_list(conf_data->vs);
-
- FREE_PTR(conf_data->lvs_id);
- FREE_PTR(conf_data->email_from);
- FREE(conf_data);
-}
-void dump_data(void)
-{
- if (conf_data->lvs_id ||
- conf_data->smtp_server ||
- conf_data->smtp_connection_to ||
- conf_data->email_from) {
- syslog(LOG_INFO, "------< Global definitions >------");
- }
- if (conf_data->lvs_id)
- syslog(LOG_INFO, " LVS ID = %s", conf_data->lvs_id);
- if (conf_data->smtp_server)
- syslog(LOG_INFO, " Smtp server = %s", ip_ntoa(conf_data->smtp_server));
- if (conf_data->smtp_connection_to)
- syslog(LOG_INFO, " Smtp server connection timeout = %d"
- , conf_data->smtp_connection_to);
- if (conf_data->email_from) {
- syslog(LOG_INFO, " Email notification from = %s"
- , conf_data->email_from);
- dump_list(conf_data->email);
- }
- if (conf_data->ssl) {
- syslog(LOG_INFO, "------< SSL definitions >------");
- dump_ssl();
- }
- if (!LIST_ISEMPTY(conf_data->vrrp)) {
- syslog(LOG_INFO, "------< VRRP Topology >------");
- dump_list(conf_data->vrrp);
- }
-#ifdef _WITH_LVS_
- if (!LIST_ISEMPTY(conf_data->vs)) {
- syslog(LOG_INFO, "------< LVS Topology >------");
- syslog(LOG_INFO, " System is compiled with LVS v%d.%d.%d"
- , NVERSION(IP_VS_VERSION_CODE));
- dump_list(conf_data->vs);
- }
- dump_checkers_queue();
-#endif
-}
+2002-05-30 Alexandre Cassen <acassen@linux-vs.org>
+ * keepalived-0.5.9 released.
+ * Added support to realserver_group. The work is not yet finished since
+ it introduces new compilation design currently not supported. So please
+ do not use yet.
+ * VRRP : Review the script notification. Moved to a script per VRRP
+ instance state => Created new keywords notify_backup|master|fault
+ to run a specific script during backup|master|fault state transition.
+ * VRRP : Added support to quoted strings for notify_backup|master|fault.
+ Can now launch script passing arguments.
+ See sample directory for examples.
+ * VRRP : Added a protocol extension called "virtual_ipaddress_excluded".
+ This configuration block is similar to "virtual_ipaddress" block =>
+ those VIPs (called E-VIPs) are set throught netlink kernel channel and
+ gratuitous arp are sent over each E-VIP. The only difference is that
+ they are not added into VRRP packet adverts. This can be usefull for
+ big env where you want to run many VRRP VIPs (200 for example).
+ VRRP packet lenght are limited to a 20 VIPs, if you want more VRRP VIPs
+ add them to the "virtual_ipaddress_excluded" configuration block.
+ * VRRP : Added more logging facility when setting/removings VIPs & E-VIPs.
+ * VRRP : Created a new FSM state called become_master in charge of
+ VIPs/E-VIPs/notifications handling. The goto_master state is now a state
+ where the instance send an advert to force a new MASTER election setting
+ the instance into a transition mode. If election success its finaly
+ transit to become_master state to own VIPs/E-VIPs and launch scripts.
+ * VRRP : Force a new MASTER election when receiving a lower prio advert.
+ * VRRP : Review the vrrp_scheduler.c to use more conventional FSM design.
+ This reduce and beautifull the code.
+ * VRRP : Fixed a very noisy flapping issue observed on heavy loaded env.
+ Simulating big traffic on a backbone figure out this flapping issue.
+ Added support to a TIMER_MICRO_ADJUST to prevent against timer degradation.
+ This can be view as a DOS protection policy. VRRP MASTER timers are adjusted
+ if they are too degradated, due to heavy loaded networking env introducing
+ latency receiving/sending VRRP protocol adverts.
+ Thanks goes to Paul, <xerox@foonet.net> for pointing it out and providing
+ access to its Internet routing backbone.
+
2002-05-21 Alexandre Cassen <acassen@linux-vs.org>
* keepalived-0.5.8 released.
* Added an OpenSSL Licence exception to grant Keepalived compilation
* Added connection port selection for Healthcheckers (TCP_CHECK,
HTTP|SSL_GET). Can be usefull for Healthcheck in fwmark LVS topology
for grouping service.
- Thanks to Richard L. Allbery, <rla@prideindustries.com> for suggesting.
+ Thanks to Richard L. Allbery, <rla@prideindustries.com> for suggection.
See samples directory for examples.
* Fixed some IPVS exclusion code when running --disable-lvs.
* Added support to VirtualHost selection when using HTTP|SSL_GET.
* Cometics patches in IPVS wrapper framework.
* Added support to quoted string. This can be usefull if you are using
MISC_CHECK and you want to pass arguments to called script. See samples.
- Thanks to Benoit Gaussen, <ben@trez42.net> for suggesting.
* Prepare work on real_server_group in order to group some realserver
declaration.
* VRRP : Fixed a password length exception causing an unwanted dropping
*
* Part: Checkers registration.
*
- * Version: $Id: check_api.c,v 0.5.8 2002/05/21 16:09:46 acassen Exp $
+ * Version: $Id: check_api.c,v 0.5.9 2002/05/30 16:05:31 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
*
* Part: Checkers arguments structures definitions.
*
- * Version: $Id: check_api.h,v 0.5.8 2002/05/21 16:09:46 acassen Exp $
+ * Version: $Id: check_api.h,v 0.5.9 2002/05/30 16:05:31 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
*
* Part: WEB CHECK. Common HTTP/SSL checker primitives.
*
- * Version: $Id: check_http.c,v 0.5.8 2002/05/21 16:09:46 acassen Exp $
+ * Version: $Id: check_http.c,v 0.5.9 2002/05/30 16:05:31 acassen Exp $
*
* Authors: Alexandre Cassen, <acassen@linux-vs.org>
* Jan Holmberg, <jan@artech.net>
*
* Part: check_http.c include file.
*
- * Version: $Id: check_http.h,v 0.5.8 2002/05/21 16:09:46 acassen Exp $
+ * Version: $Id: check_http.h,v 0.5.9 2002/05/30 16:05:31 acassen Exp $
*
* Authors: Alexandre Cassen, <acassen@linux-vs.org>
* Jan Holmberg, <jan@artech.net>
* Part: MISC CHECK. Perform a system call to run an extra
* system prog or script.
*
- * Version: $Id: check_misc.c,v 0.5.8 2002/05/21 16:09:46 acassen Exp $
+ * Version: $Id: check_misc.c,v 0.5.9 2002/05/30 16:05:31 acassen Exp $
*
* Authors: Alexandre Cassen, <acassen@linux-vs.org>
* Eric Jarman, <ehj38230@cmsu2.cmsu.edu>
*
* Part: check_misc.c include file.
*
- * Version: $Id: check_misc.h,v 0.5.8 2002/05/21 16:09:46 acassen Exp $
+ * Version: $Id: check_misc.h,v 0.5.9 2002/05/30 16:05:31 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
* Eric Jarman, <ehj38230@cmsu2.cmsu.edu>
* url, compute a MD5 over this result and match it to the
* expected value.
*
- * Version: $Id: check_ssl.c,v 0.5.8 2002/05/21 16:09:46 acassen Exp $
+ * Version: $Id: check_ssl.c,v 0.5.9 2002/05/30 16:05:31 acassen Exp $
*
* Authors: Alexandre Cassen, <acassen@linux-vs.org>
* Jan Holmberg, <jan@artech.net>
*
* Part: check_http.c include file.
*
- * Version: $Id: check_http.h,v 0.5.8 2002/05/21 16:09:46 acassen Exp $
+ * Version: $Id: check_http.h,v 0.5.9 2002/05/30 16:05:31 acassen Exp $
*
* Authors: Alexandre Cassen, <acassen@linux-vs.org>
* Jan Holmberg, <jan@artech.net>
*
* Part: TCP checker.
*
- * Version: $Id: check_tcp.c,v 0.5.8 2002/05/21 16:09:46 acassen Exp $
+ * Version: $Id: check_tcp.c,v 0.5.9 2002/05/30 16:05:31 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
*
* Part: check_tcp.c include file.
*
- * Version: $Id: check_tcp.h,v 0.5.8 2002/05/21 16:09:46 acassen Exp $
+ * Version: $Id: check_tcp.h,v 0.5.9 2002/05/30 16:05:31 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
*
* Part: Main program structure.
*
- * Version: $Id: main.c,v 0.5.8 2002/05/21 16:09:46 acassen Exp $
+ * Version: $Id: main.c,v 0.5.9 2002/05/30 16:05:31 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
*
* Part: Daemon process handling.
*
- * Version: $Id: daemon.h,v 0.5.8 2002/05/21 16:09:46 acassen Exp $
+ * Version: $Id: daemon.h,v 0.5.9 2002/05/30 16:05:31 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
*
* Part: Dynamic data structure definition.
*
- * Version: $Id: data.c,v 0.5.8 2002/05/21 16:09:46 acassen Exp $
+ * Version: $Id: data.c,v 0.5.9 2002/05/30 16:05:31 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
FREE_PTR(vrrp->isync);
FREE_PTR(vrrp->lvs_syncd_if);
FREE_PTR(vrrp->vaddr);
+ FREE_PTR(vrrp->evaddr);
+ FREE_PTR(vrrp->script_backup);
+ FREE_PTR(vrrp->script_master);
+ FREE_PTR(vrrp->script_fault);
FREE(vrrp->ipsecah_counter);
FREE(vrrp);
}
syslog(LOG_INFO, " VIP count = %d", vrrp->naddr);
for (i = 0; i < vrrp->naddr; i++)
syslog(LOG_INFO, " VIP%d = %s", i+1, ip_ntoa(vrrp->vaddr[i].addr));
- if (vrrp->notify_exec)
- syslog(LOG_INFO, " Using notification script = %s"
- , vrrp->notify_file);
+ if (vrrp->neaddr) {
+ syslog(LOG_INFO, " Excluded VIP count = %d", vrrp->neaddr);
+ for (i = 0; i < vrrp->neaddr; i++)
+ syslog(LOG_INFO, " E-VIP%d = %s", i+1, ip_ntoa(vrrp->evaddr[i].addr));
+ }
+ if (vrrp->script_backup)
+ syslog(LOG_INFO, " Backup state transition script = %s"
+ , vrrp->script_backup);
+ if (vrrp->script_master)
+ syslog(LOG_INFO, " Master state transition script = %s"
+ , vrrp->script_master);
+ if (vrrp->script_fault)
+ syslog(LOG_INFO, " Fault state transition script = %s"
+ , vrrp->script_fault);
if (vrrp->smtp_alert)
syslog(LOG_INFO, " Using smtp notification");
}
vrrp->vaddr[vrrp->naddr-1].addr = ipaddr;
vrrp->vaddr[vrrp->naddr-1].set = 0;
}
+void alloc_vrrp_evip(char *vip)
+{
+ vrrp_rt *vrrp = LIST_TAIL_DATA(conf_data->vrrp);
+ uint32_t ipaddr = inet_addr(vip);
+
+ vrrp->neaddr++;
+ if (vrrp->evaddr)
+ vrrp->evaddr = REALLOC(vrrp->evaddr, vrrp->neaddr*sizeof(*vrrp->evaddr));
+ else
+ vrrp->evaddr = (vip_addr *)MALLOC(sizeof(*vrrp->evaddr));
+ vrrp->evaddr[vrrp->neaddr-1].addr = ipaddr;
+ vrrp->evaddr[vrrp->neaddr-1].set = 0;
+}
/* Virtual server facility functions */
static void free_vs(void *data)
FREE_PTR(vs->s_svr);
if (!LIST_ISEMPTY(vs->rs))
free_list(vs->rs);
+ if (!LIST_ISEMPTY(vs->rs_group))
+ free_list(vs->rs_group);
FREE(vs);
}
static void dump_vs(void *data)
}
if (!LIST_ISEMPTY(vs->rs))
dump_list(vs->rs);
+ if (!LIST_ISEMPTY(vs->rs_group))
+ dump_list(vs->rs_group);
}
void alloc_vs(char *ip, char *port)
{
if (LIST_ISEMPTY(vs->rs))
vs->rs = alloc_list(free_rs, dump_rs);
list_add(vs->rs, new);
+ vs->last_rs_type = RS;
+}
+
+/* Real server group facility functions */
+static void free_group(void *data)
+{
+ real_server_group *group = data;
+ FREE(group->gname);
+ if (!LIST_ISEMPTY(group->rs))
+ free_list(group->rs);
+// if (!LIST_ISEMPTY(group->vs))
+// free_list(group->vs);
+ FREE(group);
+}
+static void dump_group(void *data)
+{
+ real_server_group *group = data;
+ syslog(LOG_INFO, " Real Server Group = %s", group->gname);
+ dump_list(group->rs);
+}
+void alloc_rsgroup(char *ip, char *port)
+{
+ real_server_group *group = LIST_TAIL_DATA(conf_data->group);
+ real_server *new;
+
+ new = (real_server *)MALLOC(sizeof(real_server));
+
+ new->addr_ip = inet_addr(ip);
+ new->addr_port = htons(atoi(port));
+ new->alive = 1;
+
+ if (LIST_ISEMPTY(group->rs))
+ group->rs = alloc_list(free_rs, dump_rs);
+ list_add(group->rs, new);
+}
+void alloc_group(char *name)
+{
+ real_server_group *new;
+ int size = strlen(name);
+
+ new = (real_server_group *)MALLOC(sizeof(real_server_group));
+
+ new->gname = (char *)MALLOC(size+1);
+ memcpy(new->gname, name, size);
+ list_add(conf_data->group, new);
+}
+static real_server_group *get_group_by_name(char *name)
+{
+ real_server_group *group;
+ element e;
+
+ for (e = LIST_HEAD(conf_data->group); e; ELEMENT_NEXT(e)) {
+ group = ELEMENT_DATA(e);
+ if (strcmp(group->gname, name) == 0)
+ return group;
+ }
+ return NULL;
+}
+static void dump_rs_group(void *data)
+{
+ real_server_group *group = data;
+ syslog(LOG_INFO, " Linking Real Server Group = %s", group->gname);
+}
+void set_rsgroup(char *gname)
+{
+ real_server_group *group = get_group_by_name(gname);
+ virtual_server *vs = LIST_TAIL_DATA(conf_data->vs);
+
+ if (group) {
+ if (LIST_ISEMPTY(vs->rs_group))
+ vs->rs_group = alloc_list(NULL, dump_rs_group);
+ list_add(vs->rs_group, group);
+ vs->last_rs_type = RS_GROUP;
+ }
}
/* data facility functions */
new->email = alloc_list(free_email, dump_email);
new->vrrp = alloc_list(free_vrrp, dump_vrrp);
new->vs = alloc_list(free_vs, dump_vs);
+ new->group = alloc_list(free_group, dump_group);
return new;
}
free_list(conf_data->email);
free_list(conf_data->vrrp);
free_list(conf_data->vs);
+ free_list(conf_data->group);
FREE_PTR(conf_data->lvs_id);
FREE_PTR(conf_data->email_from);
syslog(LOG_INFO, "------< VRRP Topology >------");
dump_list(conf_data->vrrp);
}
+ if (!LIST_ISEMPTY(conf_data->group)) {
+ syslog(LOG_INFO, "------< Real Servers groups >------");
+ dump_list(conf_data->group);
+ }
#ifdef _WITH_LVS_
if (!LIST_ISEMPTY(conf_data->vs)) {
syslog(LOG_INFO, "------< LVS Topology >------");
*
* Part: Dynamic data structure definition.
*
- * Version: $Id: data.h,v 0.5.8 2002/05/21 16:09:46 acassen Exp $
+ * Version: $Id: data.h,v 0.5.9 2002/05/30 16:05:31 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
int alive;
} real_server;
+/* Real server group list */
+typedef struct _real_server_group {
+ char *gname;
+ list rs;
+// list vs;
+} real_server_group;
+
/* Virtual Server definition */
typedef struct _virtual_server {
uint32_t addr_ip;
char *virtualhost;
real_server *s_svr;
list rs;
+ list rs_group;
+ int last_rs_type;
+#define RS (1 << 0)
+#define RS_GROUP (1 << 1)
} virtual_server;
/* email link list */
list email;
list vrrp;
list vs;
+ list group;
} data;
/* macro utility */
extern SSL_DATA *alloc_ssl(void);
extern void alloc_vrrp(char *iname);
extern void alloc_vrrp_vip(char *vip);
+extern void alloc_vrrp_evip(char *vip);
extern void alloc_vs(char *ip, char *port);
extern void alloc_rs(char *ip, char *port);
extern void alloc_ssvr(char *ip, char *port);
+extern void alloc_group(char *name);
+extern void alloc_rsgroup(char *ip, char *port);
+extern void set_rsgroup(char *gname);
extern data *alloc_data(void);
extern void free_data(void);
* library to add/remove server MASQ rules to the kernel
* firewall framework.
*
- * Version: $Id: ipfwwrapper.c,v 0.5.8 2002/05/21 16:09:46 acassen Exp $
+ * Version: $Id: ipfwwrapper.c,v 0.5.9 2002/05/30 16:05:31 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
ctl.ipfw.fw_src.s_addr = SVR_IP(rs) & vs->nat_mask;
ctl.ipfw.fw_smsk.s_addr = vs->nat_mask;
- ctl.ipfw.fw_spts[0] = ctl.ipfw.fw_spts[1] = ntohs(rs->addr_port);
+ ctl.ipfw.fw_spts[0] = ctl.ipfw.fw_spts[1] = htons(SVR_PORT(rs));
ctl.ipfw.fw_dpts[0] = 0x0000;
ctl.ipfw.fw_dpts[1] = 0xFFFF;
ctl.ipfw.fw_tosand = 0xFF;
*
* Part: ipfwwrapper.c include file.
*
- * Version: $Id: ipfwwrapper.h,v 0.5.8 2002/05/21 16:09:46 acassen Exp $
+ * Version: $Id: ipfwwrapper.h,v 0.5.9 2002/05/30 16:05:31 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
* Part: IPVS Kernel wrapper. Use setsockopt call to add/remove
* server to/from the loadbalanced server pool.
*
- * Version: $Id: ipvswrapper.c,v 0.5.8 2002/05/21 16:09:46 acassen Exp $
+ * Version: $Id: ipvswrapper.c,v 0.5.9 2002/05/30 16:05:31 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
*
* Part: ipvswrapper.c include file.
*
- * Version: $Id: ipvswrapper.h,v 0.5.8 2002/05/21 16:09:46 acassen Exp $
+ * Version: $Id: ipvswrapper.h,v 0.5.9 2002/05/30 16:05:31 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
*
* Part: Manipulation functions for IPVS & IPFW wrappers.
*
- * Version: $id: ipwrapper.c,v 0.5.8 2002/05/21 16:09:46 acassen Exp $
+ * Version: $id: ipwrapper.c,v 0.5.9 2002/05/30 16:05:31 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
int clear_service_vs(virtual_server *vs)
{
+ element e;
+ real_server_group *group;
+
/* Processing real server queue */
if (!LIST_ISEMPTY(vs->rs))
if (!clear_service_rs(vs, vs->rs))
return 0;
+
+ /* Processing real server group queue */
+ if (!LIST_ISEMPTY(vs->rs_group)) {
+ for (e = LIST_HEAD(vs->rs_group); e; ELEMENT_NEXT(e)) {
+ group = ELEMENT_DATA(e);
+ if (!clear_service_rs(vs, group->rs))
+ return 0;
+ }
+ }
+
if (!ipvs_cmd(LVS_CMD_DEL, vs, NULL))
return 0;
return 1;
for (e = LIST_HEAD(vs); e; ELEMENT_NEXT(e)) {
vsvr = ELEMENT_DATA(e);
- rsvr = (real_server *)LIST_HEAD(vsvr->rs);
+ rsvr = ELEMENT_DATA(LIST_HEAD(vsvr->rs));
if (!clear_service_vs(vsvr))
return 0;
int init_service_vs(virtual_server *vs)
{
+ element e;
+ real_server_group *group;
+
/* Init the IPVS root */
if (!ipvs_cmd(LVS_CMD_ADD, vs, NULL))
return 0;
if (!LIST_ISEMPTY(vs->rs))
if (!init_service_rs(vs, vs->rs))
return 0;
+
+ /* Processing real server group queue */
+ if (!LIST_ISEMPTY(vs->rs_group)) {
+ for (e = LIST_HEAD(vs->rs_group); e; ELEMENT_NEXT(e)) {
+ group = ELEMENT_DATA(e);
+ if (!init_service_rs(vs, group->rs))
+ return 0;
+ }
+ }
return 1;
}
for (e = LIST_HEAD(vs); e; ELEMENT_NEXT(e)) {
vsvr = ELEMENT_DATA(e);
- rsvr = (real_server *)LIST_HEAD(vsvr->rs);
+ rsvr = ELEMENT_DATA(LIST_HEAD(vsvr->rs));
if (!init_service_vs(vsvr))
return 0;
*
* Part: ipwrapper.c include file.
*
- * Version: $Id: ipwrapper.h,v 0.5.8 2002/05/21 16:09:46 acassen Exp $
+ * Version: $Id: ipwrapper.h,v 0.5.9 2002/05/30 16:05:31 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
* Part: Layer4 checkers handling. Register worker threads &
* upper layer checkers.
*
- * Version: $Id: layer4.c,v 0.5.8 2002/05/21 16:09:46 acassen Exp $
+ * Version: $Id: layer4.c,v 0.5.9 2002/05/30 16:05:31 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
*
* Part: layer4.c include file.
*
- * Version: $Id: layer4.h,v 0.5.8 2002/05/21 16:09:46 acassen Exp $
+ * Version: $Id: layer4.h,v 0.5.9 2002/05/30 16:05:31 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
*
* Part: List structure manipulation.
*
- * Version: $Id: list.c,v 0.5.8 2002/05/21 16:09:46 acassen Exp $
+ * Version: $Id: list.c,v 0.5.9 2002/05/30 16:05:31 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
*
* Part: list.c include file.
*
- * Version: $Id: list.h,v 0.5.8 2002/05/21 16:09:46 acassen Exp $
+ * Version: $Id: list.h,v 0.5.9 2002/05/30 16:05:31 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
*
* Part: Main program structure.
*
- * Version: $Id: main.c,v 0.5.8 2002/05/21 16:09:46 acassen Exp $
+ * Version: $Id: main.c,v 0.5.9 2002/05/30 16:05:31 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
*
* Part: Main program include file.
*
- * Version: $Id: main.h,v 0.5.8 2002/05/21 16:09:46 acassen Exp $
+ * Version: $Id: main.h,v 0.5.9 2002/05/30 16:05:31 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
/* Build version */
#define PROG "Keepalived"
-#define VERSION_CODE 0x000508
-#define DATE_CODE 0x150502
+#define VERSION_CODE 0x000509
+#define DATE_CODE 0x1E0502
#define KEEPALIVED_VERSION(version) \
(version >> 16) & 0xFF, \
* Part: Memory management framework. This framework is used to
* find any memory leak.
*
- * Version: $Id: memory.c,v 0.5.8 2002/05/21 16:09:46 acassen Exp $
+ * Version: $Id: memory.c,v 0.5.9 2002/05/30 16:05:31 acassen Exp $
*
* Authors: Alexandre Cassen, <acassen@linux-vs.org>
* Jan Holmberg, <jan@artech.net>
*
* Part: memory.c include file.
*
- * Version: $Id: memory.h,v 0.5.8 2002/05/21 16:09:46 acassen Exp $
+ * Version: $Id: memory.h,v 0.5.9 2002/05/30 16:05:31 acassen Exp $
*
* Authors: Alexandre Cassen, <acassen@linux-vs.org>
* Jan Holmberg, <jan@artech.net>
* data structure representation the conf file representing
* the loadbalanced server pool.
*
- * Version: $Id: parser.c,v 0.5.8 2002/05/21 16:09:46 acassen Exp $
+ * Version: $Id: parser.c,v 0.5.9 2002/05/30 16:05:31 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
vrrp_rt *vrrp = LIST_TAIL_DATA(conf_data->vrrp);
vrrp->preempt = !vrrp->preempt;
}
-static void vrrp_notify_handler(vector strvec)
+static void vrrp_notify_backup_handler(vector strvec)
{
vrrp_rt *vrrp = LIST_TAIL_DATA(conf_data->vrrp);
- char *str = VECTOR_SLOT(strvec, 1);
- int size = sizeof(vrrp->notify_file);
-
- memcpy(vrrp->notify_file, str, size);
+ vrrp->script_backup = set_value(strvec);
+ vrrp->notify_exec = 1;
+}
+static void vrrp_notify_master_handler(vector strvec)
+{
+ vrrp_rt *vrrp = LIST_TAIL_DATA(conf_data->vrrp);
+ vrrp->script_master = set_value(strvec);
+ vrrp->notify_exec = 1;
+}
+static void vrrp_notify_fault_handler(vector strvec)
+{
+ vrrp_rt *vrrp = LIST_TAIL_DATA(conf_data->vrrp);
+ vrrp->script_fault = set_value(strvec);
vrrp->notify_exec = 1;
}
static void vrrp_smtp_handler(vector strvec)
{
vrrp_rt *vrrp = LIST_TAIL_DATA(conf_data->vrrp);
char *str = VECTOR_SLOT(strvec, 1);
- int size = sizeof(vrrp->auth_data);
+ int max_size = sizeof(vrrp->auth_data);
+ int size;
+ size = (strlen(str) >= max_size)?max_size-1:strlen(str);
memcpy(vrrp->auth_data, str, size);
}
static void vrrp_vip_handler(vector strvec)
{
vector vips = read_value_block();
vrrp_rt *vrrp = LIST_TAIL_DATA(conf_data->vrrp);
- char *str;
int i;
int nbvip = 0;
} else
nbvip = VECTOR_SIZE(vips);
- for (i = 0; i < nbvip; i++) {
- str = VECTOR_SLOT(vips, i);
- alloc_vrrp_vip(str);
- }
+ for (i = 0; i < nbvip; i++)
+ alloc_vrrp_vip(VECTOR_SLOT(vips, i));
+ free_strvec(vips);
+}
+static void vrrp_evip_handler(vector strvec)
+{
+ vector vips = read_value_block();
+ int i;
+ for (i = 0; i < VECTOR_SIZE(vips); i++)
+ alloc_vrrp_evip(VECTOR_SLOT(vips, i));
free_strvec(vips);
}
+#ifdef _WITH_LVS_
+/* Real Servers groups handlers */
+static void group_handler(vector strvec)
+{
+ alloc_group(VECTOR_SLOT(strvec, 1));
+}
+static void rsgroup_handler(vector strvec)
+{
+ alloc_rsgroup(VECTOR_SLOT(strvec, 1), VECTOR_SLOT(strvec, 2));
+}
+static void group_weight_handler(vector strvec)
+{
+ real_server_group *group = LIST_TAIL_DATA(conf_data->group);
+ real_server *rs = LIST_TAIL_DATA(group->rs);
+ rs->weight = atoi(VECTOR_SLOT(strvec, 1));
+}
+
/* Virtual Servers handlers */
static void vs_handler(vector strvec)
{
}
static void lbkind_handler(vector strvec)
{
-#ifdef _WITH_LVS_
virtual_server *vs = LIST_TAIL_DATA(conf_data->vs);
char *str = VECTOR_SLOT(strvec, 1);
else
syslog(LOG_DEBUG, "PARSER : unknown [%s] routing method."
, str);
-#endif
}
static void natmask_handler(vector strvec)
{
rs->weight = atoi(VECTOR_SLOT(strvec, 1));
}
+/* Real Servers Groups for VS handlers */
+static void realgroup_handler(vector strvec)
+{
+ set_rsgroup(VECTOR_SLOT(strvec, 1));
+}
+#endif
+
/* recursive configuration stream handler */
static void process_stream(vector keywords)
{
install_keyword("priority", &vrrp_prio_handler);
install_keyword("advert_int", &vrrp_adv_handler);
install_keyword("virtual_ipaddress", &vrrp_vip_handler);
+ install_keyword("virtual_ipaddress_excluded", &vrrp_evip_handler);
install_keyword("sync_instance", &vrrp_isync_handler);
install_keyword("preempt", &vrrp_preempt_handler);
install_keyword("debug", &vrrp_debug_handler);
- install_keyword("notify", &vrrp_notify_handler);
+ install_keyword("notify_backup", &vrrp_notify_backup_handler);
+ install_keyword("notify_master", &vrrp_notify_master_handler);
+ install_keyword("notify_fault", &vrrp_notify_fault_handler);
install_keyword("smtp_alert", &vrrp_smtp_handler);
install_keyword("lvs_sync_daemon_interface", &vrrp_lvs_syncd_handler);
install_keyword("authentication", NULL);
install_sublevel_end();
#ifdef _WITH_LVS_
+ /* Real server group mapping */
+ install_keyword_root("real_server_group", &group_handler);
+ install_keyword("real_server", &rsgroup_handler);
+ install_sublevel();
+ install_keyword("weight", &group_weight_handler);
+ install_sublevel_end();
+
/* Virtual server mapping */
install_keyword_root("virtual_server", &vs_handler);
install_keyword("delay_loop", &delay_handler);
/* Checkers mapping */
install_checkers_keyword();
install_sublevel_end();
+
+ /* VS group mapping */
+ install_keyword("real_group", &realgroup_handler);
+ install_sublevel();
+ install_checkers_keyword();
+ install_sublevel_end();
#endif
}
*
* Part: cfreader.c include file.
*
- * Version: $Id: parser.h,v 0.5.8 2002/05/21 16:09:46 acassen Exp $
+ * Version: $Id: parser.h,v 0.5.9 2002/05/30 16:05:31 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
*
* Part: pidfile utility.
*
- * Version: $Id: pidfile.c,v 0.5.8 2002/05/21 16:09:46 acassen Exp $
+ * Version: $Id: pidfile.c,v 0.5.9 2002/05/30 16:05:31 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
*
* Part: pidfile.c include file.
*
- * Version: $Id: pidfile.h,v 0.5.8 2002/05/21 16:09:46 acassen Exp $
+ * Version: $Id: pidfile.h,v 0.5.9 2002/05/30 16:05:31 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
virtual_server fwmark 1 {
delay_loop 6
- lb_algo rr
+ lb_algo rr
lb_kind NAT
persistence_timeout 900
protocol TCP
real_server 192.168.201.100 {
weight 1
TCP_CHECK {
+ connect_port 80
connect_timeout 3
}
}
real_server 192.168.201.101 {
weight 1
TCP_CHECK {
+ connect_port 80
connect_timeout 3
}
}
--- /dev/null
+! Configuration File for keepalived
+! extra script call demonstration
+
+
+vrrp_instance VI_1 {
+ state MASTER
+ interface eth0
+ smtp_alert
+ virtual_router_id 51
+ priority 100
+ advert_int 1
+ authentication {
+ auth_type PASS
+ auth_pass 1111
+ }
+ virtual_ipaddress {
+ 192.168.200.16
+ 192.168.200.17
+ 192.168.200.18
+ }
+
+ notify_backup "/usr/local/bin/vrrp.sh BACKUP VI_1"
+ notify_master "/usr/local/bin/vrrp.sh MASTER VI_1"
+ notify_fault "/usr/local/bin/vrrp.sh FAULT VI_1"
+
+}
* the thread management routine (thread.c) present in the
* very nice zebra project (http://www.zebra.org).
*
- * Version: $Id: scheduler.c,v 0.5.8 2002/05/21 16:09:46 acassen Exp $
+ * Version: $Id: scheduler.c,v 0.5.9 2002/05/30 16:05:31 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
*
* Part: scheduler.c include file.
*
- * Version: $Id: scheduler.h,v 0.5.8 2002/05/21 16:09:46 acassen Exp $
+ * Version: $Id: scheduler.h,v 0.5.9 2002/05/30 16:05:31 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
* using the smtp protocol according to the RFC 821. A non blocking
* timeouted connection is used to handle smtp protocol.
*
- * Version: $Id: smtp.c,v 0.5.8 2002/05/21 16:09:46 acassen Exp $
+ * Version: $Id: smtp.c,v 0.5.9 2002/05/30 16:05:31 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
*
* Part: smtp.c include file.
*
- * Version: $Id: smtp.h,v 0.5.8 2002/05/21 16:09:46 acassen Exp $
+ * Version: $Id: smtp.h,v 0.5.9 2002/05/30 16:05:31 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
*
* Part: Timer manipulations.
*
- * Version: $Id: timer.c,v 0.5.8 2002/05/21 16:09:46 acassen Exp $
+ * Version: $Id: timer.c,v 0.5.9 2002/05/30 16:05:31 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
*
* Part: timer.c include file.
*
- * Version: $Id: timer.h,v 0.5.8 2002/05/21 16:09:46 acassen Exp $
+ * Version: $Id: timer.h,v 0.5.9 2002/05/30 16:05:31 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
#define TIMER_SEC(T) ((T).tv_sec)
#define TIMER_ISNULL(T) ((T).tv_sec == 0 && (T).tv_usec == 0)
#define TIMER_RESET(T) (memset(&(T), 0, sizeof(struct timeval)))
+#define TIMER_MICRO_ADJUST(T) ((T) = ((T) < TIMER_MAX_SEC)?TIMER_MAX_SEC:(T))
/* prototypes */
extern TIMEVAL timer_now(void);
*
* Part: General program utils.
*
- * Version: $Id: utils.c,v 0.5.8 2002/05/21 16:09:46 acassen Exp $
+ * Version: $Id: utils.c,v 0.5.9 2002/05/30 16:05:31 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
*
* Part: utils.h include file.
*
- * Version: $Id: utils.h,v 0.5.8 2002/05/21 16:09:46 acassen Exp $
+ * Version: $Id: utils.h,v 0.5.9 2002/05/30 16:05:31 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
*
* Part: Vector structure manipulation.
*
- * Version: $Id: vector.c,v 0.5.8 2002/05/21 16:09:46 acassen Exp $
+ * Version: $Id: vector.c,v 0.5.9 2002/05/30 16:05:31 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
*
* Part: vector.c include file.
*
- * Version: $Id: vector.h,v 0.5.8 2002/05/21 16:09:46 acassen Exp $
+ * Version: $Id: vector.h,v 0.5.9 2002/05/30 16:05:31 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
* master fails, a backup server takes over.
* The original implementation has been made by jerome etienne.
*
- * Version: $Id: vrrp.c,v 0.5.8 2002/05/21 16:09:46 acassen Exp $
+ * Version: $Id: vrrp.c,v 0.5.9 2002/05/30 16:05:31 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
*/
/* local include */
+#include <ctype.h>
#include "vrrp_scheduler.h"
#include "ipvswrapper.h"
#include "vrrp.h"
close(fd++);
}
-static char *notify_get_name(vrrp_rt *vrrp)
+static char *notify_get_script(vrrp_rt *vrrp, int state)
{
- static char notifyfile[FILENAME_MAX+1];
-
- if (vrrp->notify_exec) {
- if (vrrp->notify_file != NULL)
- strncpy(notifyfile, vrrp->notify_file, FILENAME_MAX);
- else
- snprintf(notifyfile, sizeof(notifyfile),"%s/" VRRP_NOTIFY_FORMAT
- , VRRP_NOTIFY_DFL
- , IF_NAME(vrrp->ifp)
- , vrrp->vrid );
- }
- return notifyfile;
+ if (!vrrp->notify_exec)
+ return NULL;
+ if (state == VRRP_STATE_BACK)
+ return vrrp->script_backup;
+ if (state == VRRP_STATE_MAST)
+ return vrrp->script_master;
+ if (state == VRRP_STATE_FAULT)
+ return vrrp->script_fault;
+ return NULL;
+}
+static char *notify_script_name(char *cmdline)
+{
+ char *cp = cmdline;
+ char *script;
+ int strlen;
+
+ if (!cmdline)
+ return NULL;
+ while (!isspace((int) *cp) && *cp != '\0')
+ cp++;
+ strlen = cp - cmdline;
+ script = MALLOC(strlen + 1);
+ memcpy(script, cmdline, strlen);
+ *(script + strlen) = '\0';
+
+ return script;
}
-
/* Execute extern script/program */
-static int notify_exec(vrrp_rt *vrrp , char *cmd)
+static int notify_exec(vrrp_rt *vrrp, int state)
{
- char *name = notify_get_name(vrrp);
- FILE *fOut = fopen(name, "r");
- static char mycmd[FILENAME_MAX + 1 + 32];
- char tmp[16];
+ char *script = notify_get_script(vrrp, state);
+ char *script_name = notify_script_name(script);
+ FILE *fOut;
int err;
-
pid_t pid;
+ if (!script) return 0;
+
+ fOut = fopen(script_name, "r");;
if (!fOut) {
- syslog(LOG_INFO, "Can't open %s (errno %d %s)\n", name
+ syslog(LOG_INFO, "Can't open %s (errno %d %s)"
+ , script_name
, errno
, strerror(errno));
return -1;
}
+ FREE(script_name);
fclose(fOut);
pid = fork();
/* In case of fork is error. */
if (pid < 0) {
- syslog (LOG_INFO, "Failed fork process");
+ syslog(LOG_INFO, "Failed fork process");
return -1;
}
/* In case of this is parent process. */
- if (pid) {
+ if (pid)
return (0);
- }
closeall(0);
dup(0);
dup(0);
- name = notify_get_name(vrrp);
-
- if (strlen(name) + strlen(cmd) + 32 > FILENAME_MAX + 32) {
- syslog(LOG_INFO, "To long exec stmt");
- exit (1);
- }
-
- strcpy(mycmd, name);
- strcat(mycmd, " ");
- strcat(mycmd, cmd);
- strcat(mycmd, " ");
- snprintf(tmp, 16, "%d", vrrp->vrid);
- strcat(mycmd, tmp);
-
if (vrrp->debug > 0)
- syslog(LOG_INFO, "Trying to exec %s", mycmd);
+ syslog(LOG_INFO, "Trying to exec [%s]", script);
- err = system(mycmd);
+ err = system(script);
if (err != 0) {
if (err == 127)
- syslog(LOG_ALERT, "Failed to exec %s", mycmd);
+ syslog(LOG_ALERT, "Failed to exec [%s]", script);
else
- syslog(LOG_ALERT, "Error running %s, error: %d", mycmd, err);
- }
+ syslog(LOG_ALERT, "Error running [%s], error: %d", script, err);
+ } else
+ syslog(LOG_INFO, "Success executing [%s]", script);
exit(0);
}
* add/remove VIP
* retry must clear for each vip address Hoj:-
*/
-static int vrrp_handle_ipaddress(vrrp_rt *vrrp, int cmd)
+static int vrrp_handle_ipaddress(vrrp_rt *vrrp, int cmd, int type)
{
int i, err = 0;
int retry = 0;
+ int num;
int ifindex = IF_INDEX(vrrp->ifp);
- for(i = 0; i < vrrp->naddr; i++ ) {
- vip_addr *vadd = &vrrp->vaddr[i];
+ syslog(LOG_INFO, "VRRP_Instance(%s) %s protocol %s"
+ , vrrp->iname
+ , (cmd == VRRP_IPADDRESS_ADD)?"setting":"removing"
+ , (type == VRRP_VIP_TYPE)?"VIPs.":"E-VIPs");
+
+ num = (type == VRRP_VIP_TYPE)?vrrp->naddr:vrrp->neaddr;
+ for(i = 0; i < num; i++ ) {
+ vip_addr *vadd = (type == VRRP_VIP_TYPE)?&vrrp->vaddr[i]:&vrrp->evaddr[i];
if(!cmd && !vadd->set) continue;
retry:
if (netlink_address_ipv4(ifindex , ntohl(vadd->addr), cmd) < 0) {
if (ret == VRRP_PACKET_KO)
syslog(LOG_INFO, "bogus VRRP packet received on %s !!!"
, IF_NAME(vrrp->ifp));
-// else
-// syslog(LOG_INFO, "Success receiving VRRP packet on %s."
-// , IF_NAME(vrrp->ifp));
return ret;
}
int i, j;
/* send gratuitous arp for each virtual ip */
- for (j = 0; j < 5; j++)
+ syslog(LOG_INFO, "VRRP_Instance(%s) Sending gratuitous ARP on %s"
+ , vrrp->iname
+ , IF_NAME(vrrp->ifp));
+
+ for (j = 0; j < 5; j++) {
for (i = 0; i < vrrp->naddr; i++)
send_gratuitous_arp(vrrp, ntohl(vrrp->vaddr[i].addr));
+ for (i = 0; i < vrrp->neaddr; i++)
+ send_gratuitous_arp(vrrp, ntohl(vrrp->evaddr[i].addr));
+ }
}
/* becoming master */
-void vrrp_state_goto_master(vrrp_rt *vrrp)
+void vrrp_state_become_master(vrrp_rt *vrrp)
{
- /* send an advertisement */
- vrrp_send_adv(vrrp, vrrp->priority);
-
/* add the ip addresses */
- vrrp_handle_ipaddress(vrrp, VRRP_IPADDRESS_ADD);
+ if (vrrp->naddr)
+ vrrp_handle_ipaddress(vrrp, VRRP_IPADDRESS_ADD, VRRP_VIP_TYPE);
+ if (vrrp->neaddr)
+ vrrp_handle_ipaddress(vrrp, VRRP_IPADDRESS_ADD, VRRP_EVIP_TYPE);
+ vrrp->vipset = 1;
/* remotes arp tables update */
- syslog(LOG_INFO, "Sending gratuitous ARP on %s"
- , IF_NAME(vrrp->ifp));
vrrp_send_gratuitous_arp(vrrp);
/* Check if notify is needed */
- if (vrrp->notify_exec) {
- notify_exec(vrrp, "master");
- if (vrrp->debug > 0)
- syslog(LOG_INFO, "notify:%s, flg:%d"
- , vrrp->notify_file
- , vrrp->notify_exec);
- }
+ notify_exec(vrrp, VRRP_STATE_MAST);
#ifdef _HAVE_IPVS_SYNCD_
/* Check if sync daemon handling is needed */
if (vrrp->lvs_syncd_if)
ipvs_syncd_master(vrrp->lvs_syncd_if);
#endif
+}
+
+void vrrp_state_goto_master(vrrp_rt *vrrp)
+{
+ /*
+ * Send an advertisement. To force a new master
+ * election.
+ */
+ vrrp_send_adv(vrrp, vrrp->priority);
if (vrrp->wantstate == VRRP_STATE_MAST) {
vrrp->state = VRRP_STATE_MAST;
- syslog(LOG_INFO, "VRRP_Instance(%s) Entering MASTER STATE"
+ syslog(LOG_INFO, "VRRP_Instance(%s) Transition to MASTER STATE"
, vrrp->iname);
} else {
vrrp->state = VRRP_STATE_DUMMY_MAST;
- syslog(LOG_INFO, "VRRP_Instance(%s) Entering DUMMY_MASTER STATE"
+ syslog(LOG_INFO, "VRRP_Instance(%s) Transition to DUMMY_MASTER STATE"
, vrrp->iname);
}
}
static void vrrp_restore_interface(vrrp_rt *vrrp, int advF)
{
/* remove the ip addresses */
- vrrp_handle_ipaddress(vrrp, VRRP_IPADDRESS_DEL);
+ if (VRRP_VIP_ISSET(vrrp)) {
+ if (vrrp->naddr)
+ vrrp_handle_ipaddress(vrrp, VRRP_IPADDRESS_DEL, VRRP_VIP_TYPE);
+ if (vrrp->neaddr)
+ vrrp_handle_ipaddress(vrrp, VRRP_IPADDRESS_DEL, VRRP_EVIP_TYPE);
+ vrrp->vipset = 0;
+ }
/* if we stop vrrp, warn the other routers to speed up the recovery */
if (advF)
void vrrp_state_leave_master(vrrp_rt *vrrp)
{
- /* Check if notify is needed */
- if (vrrp->notify_exec) {
- if (vrrp->wantstate == VRRP_STATE_BACK)
- notify_exec(vrrp, "backup");
- if (vrrp->wantstate == VRRP_STATE_GOTO_FAULT)
- notify_exec(vrrp, "fault");
- if (vrrp->debug > 0)
- syslog(LOG_INFO, "notify:%s, flg:%d"
- , vrrp->notify_file
- , vrrp->notify_exec);
- }
-
+ if (VRRP_VIP_ISSET(vrrp)) {
#ifdef _HAVE_IPVS_SYNCD_
- /* Check if sync daemon handling is needed */
- if (vrrp->lvs_syncd_if)
- ipvs_syncd_backup(vrrp->lvs_syncd_if);
+ /* Check if sync daemon handling is needed */
+ if (vrrp->lvs_syncd_if)
+ ipvs_syncd_backup(vrrp->lvs_syncd_if);
#endif
+ }
/* set the new vrrp state */
switch (vrrp->wantstate) {
, vrrp->iname);
vrrp_restore_interface(vrrp, 0);
vrrp->state = vrrp->wantstate;
+ notify_exec(vrrp, VRRP_STATE_BACK);
break;
case VRRP_STATE_GOTO_FAULT:
syslog(LOG_INFO, "VRRP_Instance(%s) Entering FAULT STATE"
, vrrp->iname);
vrrp_restore_interface(vrrp, 0);
vrrp->state = VRRP_STATE_FAULT;
+ notify_exec(vrrp, VRRP_STATE_FAULT);
break;
}
}
/* MASTER state processing */
void vrrp_state_master_tx(vrrp_rt *vrrp, const int prio)
{
+ if (!VRRP_VIP_ISSET(vrrp)) {
+ syslog(LOG_INFO, "VRRP_Instance(%s) Entering MASTER STATE"
+ , vrrp->iname);
+ vrrp_state_become_master(vrrp);
+ }
+
if (prio == VRRP_PRIO_OWNER)
vrrp_send_adv(vrrp, VRRP_PRIO_OWNER);
else
, vrrp->iname);
vrrp_send_adv(vrrp, vrrp->priority);
return 0;
+ } else if (hd->priority < vrrp->priority) {
+ /* We receive a lower prio adv we just refresh remote ARP cache */
+ syslog(LOG_INFO, "VRRP_Instance(%s) Received lower prio advert"
+ ", forcing new election"
+ , vrrp->iname);
+ vrrp_send_adv(vrrp, vrrp->priority);
+ vrrp_send_gratuitous_arp(vrrp);
+ return 0;
} else if (hd->priority == 0) {
vrrp_send_adv(vrrp, vrrp->priority);
return 0;
vrrp->ms_down_timer = 3 * vrrp->adver_int + VRRP_TIMER_SKEW(vrrp);
vrrp->state = VRRP_STATE_BACK;
return 1;
- } else if (hd->priority < vrrp->priority) {
- /* We receive a lower prio adv we just refresh remote ARP cache */
- vrrp_send_gratuitous_arp(vrrp);
- return 0;
}
return 0;
*
* Part: vrrp.c program include file.
*
- * Version: $Id: vrrp.h,v 0.5.8 2002/05/21 16:09:46 acassen Exp $
+ * Version: $Id: vrrp.h,v 0.5.9 2002/05/30 16:05:31 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
* Based on the Jerome Etienne, <jetienne@arobas.net> code.
#include "timer.h"
#include "utils.h"
-/* Default dir to notify file */
-#define VRRP_NOTIFY_DFL "/etc/init.d"
-
-/* notify name (vrrpd-eth0-101) */
-#define VRRP_NOTIFY_FORMAT "vrrpd-%s-%d"
-
typedef struct { /* rfc2338.5.1 */
uint8_t vers_type; /* 0-3=type, 4-7=version */
uint8_t vrid; /* virtual router id */
int vrid; /* virtual id. from 1(!) to 255 */
int priority; /* priority value */
int naddr; /* number of ip addresses */
+ int vipset; /* All the vips are set ? */
vip_addr *vaddr; /* point on the ip address array */
+ int neaddr; /* number of excluded ip addresses */
+ vip_addr *evaddr; /* list of protocol excluded VIPs.
+ * Those VIPs will not be presents into the
+ * VRRP adverts
+ */
int adver_int; /* delay between advertisements(in sec) */
char hwaddr[6]; /* VMAC -- rfc2338.7.3 */
int preempt; /* true if a higher prio preempt a lower one */
/* State transition notification */
int smtp_alert;
int notify_exec;
- char notify_file[FILENAME_MAX];
+ char *script_backup;
+ char *script_master;
+ char *script_fault;
/* rfc2336.6.2 */
uint32_t ms_down_timer;
} vrrp_rt;
/* VRRP state machine -- rfc2338.6.4 */
-#define VRRP_DISPATCHER 0 /* internal */
-#define VRRP_STATE_INIT 1 /* rfc2338.6.4.1 */
-#define VRRP_STATE_BACK 2 /* rfc2338.6.4.2 */
-#define VRRP_STATE_MAST 3 /* rfc2338.6.4.3 */
+#define VRRP_STATE_INIT 0 /* rfc2338.6.4.1 */
+#define VRRP_STATE_BACK 1 /* rfc2338.6.4.2 */
+#define VRRP_STATE_MAST 2 /* rfc2338.6.4.3 */
+#define VRRP_STATE_FAULT 3 /* internal */
#define VRRP_STATE_GOTO_MASTER 4 /* internal */
-#define VRRP_STATE_LEAVE_MASTER 5 /* internal */
-#define VRRP_STATE_GOTO_DUMMY_MAST 96 /* internal */
-#define VRRP_STATE_DUMMY_MAST 97 /* internal */
+#define VRRP_STATE_DUMMY_MAST 5 /* internal */
+#define VRRP_STATE_LEAVE_MASTER 6 /* internal */
+#define VRRP_STATE_GOTO_DUMMY_MAST 97 /* internal */
#define VRRP_STATE_GOTO_FAULT 98 /* internal */
-#define VRRP_STATE_FAULT 99 /* internal */
+#define VRRP_DISPATCHER 99 /* internal */
#define VRRP_MCAST_RETRY 10 /* internal */
+#define VRRP_MAX_FSM_STATE 5 /* internal */
/* VRRP packet handling */
#define VRRP_PACKET_OK 0
#define VRRP_MAX_VIP 20
#define VRRP_PACKET_TEMP_LEN 512
#define VRRP_AUTH_LEN 8
+#define VRRP_VIP_TYPE (1 << 0)
+#define VRRP_EVIP_TYPE (1 << 1)
#define VRRP_IS_BAD_VID(id) ((id)<1 || (id)>255) /* rfc2338.6.1.vrid */
#define VRRP_IS_BAD_PRIORITY(p) ((p)<1 || (p)>255) /* rfc2338.6.1.prio */
#define VRRP_IS_BAD_DEBUG_INT(d) ((d)<0 || (d)>4)
#define VRRP_TIMER_SKEW(srv) ((256-(srv)->priority)*TIMER_HZ/256)
+#define VRRP_VIP_ISSET(V) ((V)->vipset)
#define VRRP_MIN(a, b) ((a) < (b)?(a):(b))
#define VRRP_MAX(a, b) ((a) > (b)?(a):(b))
*
* Part: Interfaces manipulation.
*
- * Version: $Id: vrrp_if.c,v 0.5.8 2002/05/21 16:09:46 acassen Exp $
+ * Version: $Id: vrrp_if.c,v 0.5.9 2002/05/30 16:05:31 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
*
* Part: vrrp_if.c include file.
*
- * Version: $Id: vrrp_if.h,v 0.5.8 2002/05/21 16:09:46 acassen Exp $
+ * Version: $Id: vrrp_if.h,v 0.5.9 2002/05/30 16:05:31 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
*
* Part: NETLINK IPv4 address manipulation.
*
- * Version: $Id: vrrp_ipaddress.c,v 0.5.8 2002/05/21 16:09:46 acassen Exp $
+ * Version: $Id: vrrp_ipaddress.c,v 0.5.9 2002/05/30 16:05:31 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
*
* Part: vrrp_ipaddress.c include file.
*
- * Version: $Id: vrrp_ipaddress.h,v 0.5.8 2002/05/21 16:09:46 acassen Exp $
+ * Version: $Id: vrrp_ipaddress.h,v 0.5.9 2002/05/30 16:05:31 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
* authentication data encryption using HMAC MD5 according to
* RFCs 2085 & 2104.
*
- * Version: $Id: vrrp_ipsecah.c,v 0.5.8 2002/05/21 16:09:46 acassen Exp $
+ * Version: $Id: vrrp_ipsecah.c,v 0.5.9 2002/05/30 16:05:31 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
*
* Part: vrrp_ipsecah.c include file.
*
- * Version: $Id: vrrp_ipsecah.h,v 0.5.8 2002/05/21 16:09:46 acassen Exp $
+ * Version: $Id: vrrp_ipsecah.h,v 0.5.9 2002/05/30 16:05:31 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
*
* Part: NETLINK kernel command channel.
*
- * Version: $Id: vrrp_netlink.c,v 0.5.8 2002/05/21 16:09:46 acassen Exp $
+ * Version: $Id: vrrp_netlink.c,v 0.5.9 2002/05/30 16:05:31 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
*
* Part: vrrp_netlink.c include file.
*
- * Version: $Id: vrrp_netlink.h,v 0.5.8 2002/05/21 16:09:46 acassen Exp $
+ * Version: $Id: vrrp_netlink.h,v 0.5.9 2002/05/30 16:05:31 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
*
* Part: Sheduling framework for vrrp code.
*
- * Version: $Id: vrrp_scheduler.c,v 0.5.8 2002/05/21 16:09:46 acassen Exp $
+ * Version: $Id: vrrp_scheduler.c,v 0.5.9 2002/05/30 16:05:31 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
extern thread_master *master;
extern data *conf_data;
+/* VRRP FSM definition */
+static void vrrp_backup(vrrp_rt *, char *, int);
+static void vrrp_leave_master(vrrp_rt *, char *, int);
+static void vrrp_leave_fault(vrrp_rt *, char *, int);
+static void vrrp_become_master(vrrp_rt *, char *, int);
+static void vrrp_leave_dummy_master(vrrp_rt *, char *, int);
+
+static void vrrp_goto_master(vrrp_rt *);
+static void vrrp_master(vrrp_rt *);
+static void vrrp_fault(vrrp_rt *);
+static void vrrp_dummy_master(vrrp_rt *);
+
+struct {
+ void (*read) (vrrp_rt *, char *, int);
+ void (*read_to) (vrrp_rt *);
+} FSM[VRRP_MAX_FSM_STATE + 1] =
+{
+/* Stream Read Handlers | Stream Read_to handlers */
+/*-------------------------+----------------------------*/
+ {NULL, NULL},
+ {vrrp_backup, vrrp_goto_master}, /* BACKUP */
+ {vrrp_leave_master, vrrp_master}, /* MASTER */
+ {vrrp_leave_fault, vrrp_fault}, /* FAULT */
+ {vrrp_become_master, vrrp_goto_master}, /* GOTO_MASTER */
+ {vrrp_leave_dummy_master, vrrp_dummy_master} /* DUMMY_MASTER */
+};
+
/* SMTP alert notifier */
static void vrrp_smtp_notifier(vrrp_rt *vrrp)
{
timer = vrrp_compute_timer(fd);
now = timer_now();
vrrp_timer = timer_sub(timer, now);
-// vrrp_timer = timer_sub_now(timer);
return (vrrp_timer.tv_sec*TIMER_HZ + vrrp_timer.tv_usec);
}
return NULL;
}
-static void vrrp_handle_backup(vrrp_rt *vrrp
- , char *vrrp_buffer
- , int len)
+static void vrrp_backup(vrrp_rt *vrrp
+ , char *vrrp_buffer
+ , int len)
{
struct iphdr *iph = (struct iphdr *)vrrp_buffer;
ipsec_ah *ah;
vrrp_state_backup(vrrp, vrrp_buffer, len);
}
-static void vrrp_handle_become_master(vrrp_rt *vrrp
+static void vrrp_become_master(vrrp_rt *vrrp
, char *vrrp_buffer
, int len)
{
vrrp_smtp_notifier(vrrp);
}
-static void vrrp_handle_leave_master(vrrp_rt *vrrp
+static void vrrp_leave_master(vrrp_rt *vrrp
, char *vrrp_buffer
, int len)
{
}
}
-static void vrrp_handle_leave_fault(vrrp_rt *vrrp
+static void vrrp_leave_fault(vrrp_rt *vrrp
, char *vrrp_buffer
, int len)
{
IF_ISUP(vrrp_isync->ifp))) {
syslog(LOG_INFO, "VRRP_Instance(%s) prio is higher than received advert"
, vrrp->iname);
- vrrp_handle_become_master(vrrp, vrrp_buffer, len);
+ vrrp_become_master(vrrp, vrrp_buffer, len);
}
} else {
syslog(LOG_INFO, "VRRP_Instance(%s) prio is higher than received advert"
, vrrp->iname);
- vrrp_handle_become_master(vrrp, vrrp_buffer, len);
+ vrrp_become_master(vrrp, vrrp_buffer, len);
}
} else {
vrrp->state = VRRP_STATE_BACK;
}
}
-static void vrrp_handle_leave_dummy_master(vrrp_rt *vrrp
+static void vrrp_leave_dummy_master(vrrp_rt *vrrp
, char *vrrp_buffer
, int len)
{
vrrp->state = VRRP_STATE_BACK;
break;
case VRRP_STATE_MAST:
- vrrp_handle_become_master(vrrp, vrrp_buffer, len);
+ vrrp_become_master(vrrp, vrrp_buffer, len);
break;
}
}
}
}
-static int vrrp_handle_state(vrrp_rt *vrrp
- , char *vrrp_buffer
- , int len)
-{
- int previous_state;
-
- previous_state = vrrp->state;
-
- switch (vrrp->state) {
- case VRRP_STATE_BACK:
- vrrp_handle_backup(vrrp, vrrp_buffer, len);
- break;
- case VRRP_STATE_GOTO_MASTER:
- vrrp_handle_become_master(vrrp, vrrp_buffer, len);
- break;
- case VRRP_STATE_DUMMY_MAST:
-// vrrp_handle_leave_dummy_master(vrrp, vrrp_buffer, len);
- break;
- case VRRP_STATE_MAST:
- vrrp_handle_leave_master(vrrp, vrrp_buffer, len);
- break;
- case VRRP_STATE_FAULT:
- vrrp_handle_leave_fault(vrrp, vrrp_buffer, len);
- break;
- }
-
- return previous_state;
-}
-
-static void vrrp_handle_goto_master(vrrp_rt *vrrp)
+static void vrrp_goto_master(vrrp_rt *vrrp)
{
if (!IF_ISUP(vrrp->ifp)) {
syslog(LOG_INFO, "Kernel is reporting: interface %s DOWN"
}
}
-static void vrrp_handle_master(vrrp_rt *vrrp)
+static void vrrp_master(vrrp_rt *vrrp)
{
/* Check if interface we are running on is UP */
if (vrrp->wantstate != VRRP_STATE_GOTO_FAULT) {
}
}
-static void vrrp_handle_fault(vrrp_rt *vrrp)
+static void vrrp_fault(vrrp_rt *vrrp)
{
if (IF_ISUP(vrrp->ifp)) {
syslog(LOG_INFO, "Kernel is reporting: interface %s UP"
if (vrrp->init_state == VRRP_STATE_BACK)
vrrp->state = VRRP_STATE_BACK;
else {
- vrrp_handle_goto_master(vrrp);
+ vrrp_goto_master(vrrp);
vrrp_smtp_notifier(vrrp);
}
}
}
}
-static void vrrp_handle_dummy_master(vrrp_rt *vrrp)
+static void vrrp_dummy_master(vrrp_rt *vrrp)
{
/* Check if interface we are running on is UP */
if (!IF_ISUP(vrrp->ifp))
}
}
-static int vrrp_handle_state_timeout(vrrp_rt *vrrp)
-{
- int previous_state;
-
- previous_state = vrrp->state;
-
- switch (vrrp->state) {
- case VRRP_STATE_BACK:
- vrrp_handle_goto_master(vrrp);
- break;
- case VRRP_STATE_GOTO_MASTER:
- vrrp_handle_goto_master(vrrp);
- break;
- case VRRP_STATE_DUMMY_MAST:
- vrrp_handle_dummy_master(vrrp);
- break;
- case VRRP_STATE_MAST:
- vrrp_handle_master(vrrp);
- break;
- case VRRP_STATE_FAULT:
- vrrp_handle_fault(vrrp);
- break;
- }
-
- return previous_state;
-}
-
/* Handle dispatcher read timeout */
static int vrrp_dispatcher_read_to(int fd)
{
vrrp_rt *vrrp;
vrrp_rt *vrrp_isync;
int vrid = 0;
- int previous_state = 0;
+ int prev_state = 0;
/* Searching for matching instance */
vrid = vrrp_timer_vrid_timeout(fd);
vrrp = vrrp_search_instance(vrid);
- previous_state = vrrp_handle_state_timeout(vrrp);
+ prev_state = vrrp->state;
+ VRRP_FSM_READ_TO(vrrp);
/* handle master instance synchronization */
- if (previous_state == VRRP_STATE_BACK &&
- vrrp->state == VRRP_STATE_MAST &&
+ if (prev_state == VRRP_STATE_BACK &&
+ vrrp->state == VRRP_STATE_MAST &&
vrrp->isync) {
vrrp_isync = vrrp_search_instance_isync(vrrp->isync);
}
/* handle synchronization in FAULT state */
- if (previous_state == VRRP_STATE_MAST &&
- vrrp->state == VRRP_STATE_FAULT &&
+ if (prev_state == VRRP_STATE_MAST &&
+ vrrp->state == VRRP_STATE_FAULT &&
vrrp->isync) {
vrrp_isync = vrrp_search_instance_isync(vrrp->isync);
* => We doesn't receive remote MASTER adverts.
* => Emulate a DUMMY master to break the loop.
*/
- if (previous_state == VRRP_STATE_MAST &&
- vrrp->state == VRRP_STATE_BACK &&
+ if (prev_state == VRRP_STATE_MAST &&
+ vrrp->state == VRRP_STATE_BACK &&
vrrp->isync) {
vrrp_isync = vrrp_search_instance_isync(vrrp->isync);
struct iphdr *iph;
vrrp_pkt *hd;
int len = 0;
- int previous_state = 0;
+ int prev_state = 0;
/* allocate & clean the read buffer */
vrrp_buffer = (char *)MALLOC(VRRP_PACKET_TEMP_LEN);
return fd;
}
- previous_state = vrrp_handle_state(vrrp, vrrp_buffer, len);
+ prev_state = vrrp->state;
+ VRRP_FSM_READ(vrrp, vrrp_buffer, len);
/* handle backup instance synchronization */
- if (previous_state == VRRP_STATE_MAST &&
- vrrp->state == VRRP_STATE_BACK &&
+ if (prev_state == VRRP_STATE_MAST &&
+ vrrp->state == VRRP_STATE_BACK &&
vrrp->isync) {
vrrp_isync = vrrp_search_instance_isync(vrrp->isync);
/*
* Refresh sands only if found matching instance.
* Otherwize the packet is simply ignored...
- *
- * FIXME: Add a dropping packet framework to not
- * degrade the instance timer during dropping.
*/
vrrp_init_instance_sands(vrrp);
/* register next dispatcher thread */
vrrp_timer = vrrp_timer_fd(fd);
+ TIMER_MICRO_ADJUST(vrrp_timer);
thread_add_read(thread->master, vrrp_read_dispatcher_thread
, NULL
, fd
*
* Part: vrrp_scheduler.c include file.
*
- * Version: $Id: vrrp_scheduler.h,v 0.5.8 2002/05/21 16:09:46 acassen Exp $
+ * Version: $Id: vrrp_scheduler.h,v 0.5.9 2002/05/30 16:05:31 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
int fd;
} sock;
+/* VRRP FSM Macro */
+#define VRRP_FSM_READ_TO(V) \
+do { \
+ if ((*(FSM[(V)->state].read_to))) \
+ (*(FSM[(V)->state].read_to)) (V); \
+} while (0)
+
+#define VRRP_FSM_READ(V, B, L) \
+do { \
+ if ((*(FSM[(V)->state].read))) \
+ (*(FSM[(V)->state].read)) (V, B, L); \
+} while (0)
+
/* extern prototypes */
extern int vrrp_read_dispatcher_thread(thread *thread);