head 1.4; access; symbols OPENPKG_E1_MP_HEAD:1.4 OPENPKG_E1_MP:1.4 OPENPKG_CW_FP:1.3; locks; strict; comment @# @; 1.4 date 2005.05.15.18.38.27; author rse; state dead; branches; next 1.3; 1.3 date 2004.12.26.09.45.10; author rse; state Exp; branches; next 1.2; 1.2 date 2004.10.14.08.18.59; author rse; state Exp; branches; next 1.1; 1.1 date 2004.10.14.08.13.29; author rse; state Exp; branches; next ; desc @@ 1.4 log @FreeVRRPd is mainly BSD-only software and under FreeBSD there is already built-in CARP while on other platforms there is the 'ucarp' package. So, remove this package from our repository. @ text @5sec (= 5*100000usec) is too less for usual host/switch combinations (especially if spanning-tree is performed on the switch port, etc), so increase this to 40sec (= 8*500000usec) because performing spanning-tree algorithm on a switch port requires usually about 30sec maximum. Index: vrrp_define.h --- vrrp_define.h.orig 2003-01-30 12:50:55 +0100 +++ vrrp_define.h 2004-10-14 10:17:40 +0200 @@@@ -52,8 +52,8 @@@@ #define VRRP_DEFAULT_ADV_INT 1 #define VRRP_PROTOCOL_MAX_VRID 255 #define VRRP_CONF_FILE_NAME "/usr/local/etc/freevrrpd.conf" -#define VRRP_MONCIRCUIT_MONDELAY 1000000 -#define VRRP_MONCIRCUIT_MAX_ERRORS 5 +#define VRRP_MONCIRCUIT_MONDELAY 5000000 +#define VRRP_MONCIRCUIT_MAX_ERRORS 8 #define IPPROTO_VRRP 112 #define MAX_IP_ALIAS 255 ----------------------------------------------------------------------------- The following changes are backported from the vendor CVS as of 05-Mar-2004 to fix the Ethernet carrier state change handling. This is very important for some FreeBSD network drivers like bge(4) and em(4). Index: vrrp_conf.c --- vrrp_conf.c.orig 2003-01-30 12:50:55 +0100 +++ vrrp_conf.c 2004-12-26 10:38:24 +0100 @@@@ -141,12 +141,15 @@@@ } if (lstat(name, &st) == -1) { syslog(LOG_ERR, "cannot call lstat(): %m"); + fclose(stream); return NULL; } if ((st.st_mode & S_IFMT) != S_IFREG) { syslog(LOG_ERR, "%s is not a regular file", name); + fclose(stream); return NULL; } + return stream; } Index: vrrp_define.h --- vrrp_define.h.orig 2004-12-26 10:38:10 +0100 +++ vrrp_define.h 2004-12-26 10:38:24 +0100 @@@@ -50,6 +50,7 @@@@ #define VRRP_USEC_COEFF 1000000 #define VRRP_CONF_MAX_ARGS 255 #define VRRP_DEFAULT_ADV_INT 1 +#define VRRP_DEFAULT_CARRIER_TIMEOUT 10 #define VRRP_PROTOCOL_MAX_VRID 255 #define VRRP_CONF_FILE_NAME "/usr/local/etc/freevrrpd.conf" #define VRRP_MONCIRCUIT_MONDELAY 5000000 Index: vrrp_functions.h --- vrrp_functions.h.orig 2003-01-30 12:50:55 +0100 +++ vrrp_functions.h 2004-12-26 10:38:24 +0100 @@@@ -58,7 +58,7 @@@@ void vrrp_network_close_bpf(struct vrrp_vr *); void vrrp_network_initialize(void); char vrrp_network_open_socket(struct vrrp_vr *); -int vrrp_network_send_packet(char *, int, int, int); +ssize_t vrrp_network_send_packet(char *, int, int, int); u_int vrrp_network_vrrphdr_len(struct vrrp_vr *); void vrrp_network_init_ethhdr(char *, struct vrrp_vr *); void vrrp_network_init_iphdr(char *, struct vrrp_vr *); @@@@ -114,6 +114,6 @@@@ void vrrp_thread_mutex_unlock(void); void vrrp_thread_mutex_lock_bpf(void); void vrrp_thread_mutex_unlock_bpf(void); -void vrrp_thread_launch_vrrprouter(int *); +void vrrp_thread_launch_vrrprouter(void **); char vrrp_thread_initialize(void); char vrrp_thread_create_vrid(struct vrrp_vr *); Index: vrrp_interface.c --- vrrp_interface.c.orig 2003-01-30 12:50:55 +0100 +++ vrrp_interface.c 2004-12-26 10:38:24 +0100 @@@@ -50,10 +50,10 @@@@ char vrrp_interface_ethaddr_set(char *if_name, struct ether_addr * ethaddr) { +#if defined(SIOCSIFLLADDR) int sd; struct ifreq ifr; -#if defined(SIOCSIFLLADDR) bzero(&ifr, sizeof(ifr)); sd = socket(AF_INET, SOCK_DGRAM, 0); if (sd == -1) { Index: vrrp_main.c --- vrrp_main.c.orig 2003-01-30 12:50:55 +0100 +++ vrrp_main.c 2004-12-26 10:38:24 +0100 @@@@ -76,6 +76,7 @@@@ vr->vr_if->alive = 1; vr->vr_if->nberrors = 0; vr->vr_if->reportsyslog = 0; + vr->vr_if->carrier_timeout = VRRP_DEFAULT_CARRIER_TIMEOUT; } return; Index: vrrp_moncircuit.c --- vrrp_moncircuit.c.orig 2003-01-30 12:50:56 +0100 +++ vrrp_moncircuit.c 2004-12-26 10:38:24 +0100 @@@@ -90,6 +90,7 @@@@ int numvrid, numvrid2; int cpt; int sd; + int returnCode; sd = socket(PF_INET, SOCK_DGRAM, 0); if (sd < 0) { @@@@ -100,7 +101,10 @@@@ for (;;) { numvrid = 0; while (vr_ptr[numvrid]) { - if ((vrrp_moncircuit_interface_status(sd, vr_ptr[numvrid]->vr_if->if_name) == 1) && (! vr_ptr[numvrid]->fault)) { + vrrp_thread_mutex_lock_monitor(); + returnCode = vrrp_moncircuit_interface_status(sd, vr_ptr[numvrid]->vr_if->if_name); + vrrp_thread_mutex_unlock_monitor(); + if ((returnCode == 1) && (! vr_ptr[numvrid]->fault)) { if (vr_ptr[numvrid]->vr_if->nberrors < VRRP_MONCIRCUIT_MAX_ERRORS) { if (! vr_ptr[numvrid]->vr_if->alive) { vr_ptr[numvrid]->vr_if->alive = 1; Index: vrrp_moncircuit.h --- vrrp_moncircuit.h.orig 2003-01-30 12:50:55 +0100 +++ vrrp_moncircuit.h 2004-12-26 10:38:24 +0100 @@@@ -37,12 +37,14 @@@@ #include "vrrp_proto.h" #include "vrrp_define.h" +#include "vrrp_thread.h" /* externals */ extern struct vrrp_vr *vr_ptr[VRRP_PROTOCOL_MAX_VRID]; extern u_char vr_ptr_pos; /* Functions */ -void vrrp_moncircuit_monitor_thread(int **args); +void vrrp_moncircuit_monitor_thread(int **); +int vrrp_moncircuit_interface_status(int, char *); #endif Index: vrrp_network.c --- vrrp_network.c.orig 2003-01-30 12:50:55 +0100 +++ vrrp_network.c 2004-12-26 10:38:24 +0100 @@@@ -124,18 +124,18 @@@@ return 0; } -int +ssize_t vrrp_network_send_packet(char *buffer, int sizebuf, int sd_bpf, int log) { /* struct sockaddr_in addr; */ - size_t octets; + ssize_t octets; vrrp_thread_mutex_lock_bpf(); vrrp_network_flush_bpf(sd_bpf); octets = write(sd_bpf, buffer, sizebuf); vrrp_network_flush_bpf(sd_bpf); vrrp_thread_mutex_unlock_bpf(); - if (octets == -1) { + if (octets < 0) { if (log) syslog(LOG_ERR, "can't write to bpf socket descriptor (pseudo_device bpf not activated in kernel ?)"); return -1; @@@@ -221,7 +221,7 @@@@ { u_char *buffer; u_int len = ETHER_HDR_LEN + sizeof(struct ip) + vrrp_network_vrrphdr_len(vr); - int error; + ssize_t bytes = 0; buffer = (u_char *) malloc(len); bzero(buffer, len); @@@@ -230,17 +230,17 @@@@ vrrp_network_init_ethhdr(buffer, vr); vrrp_network_init_vrrphdr(buffer, vr); - error = vrrp_network_send_packet(buffer, len, vr->sd_bpf, ! vr->fault); - if (error < 0) { + if (vr->fault) + bytes = vrrp_network_send_packet(buffer, len, vr->sd_bpf, 0); + else + bytes = vrrp_network_send_packet(buffer, len, vr->sd_bpf, 1); + if (bytes < 0) { + syslog(LOG_ERR, "There is a big problem here !"); vr->fault = 1; free(buffer); return -1; } - else { - if (vr->fault) - vr->fault = 0; - } - + vr->fault = 0; free(buffer); return 0; Index: vrrp_proto.h --- vrrp_proto.h.orig 2003-01-30 12:50:55 +0100 +++ vrrp_proto.h 2004-12-26 10:38:24 +0100 @@@@ -73,6 +73,7 @@@@ struct ether_addr ethaddr; struct ether_addr actualethaddr; struct vrrp_ethaddr_list *p, *d; + int carrier_timeout; }; struct vrrp_vip { Index: vrrp_state.c --- vrrp_state.c.orig 2003-05-09 12:29:11 +0200 +++ vrrp_state.c 2004-12-26 10:38:24 +0100 @@@@ -51,11 +51,15 @@@@ char vrrp_state_set_master(struct vrrp_vr * vr) { + int returnCode = 0; + int counter = 0; + /* Tester si sd_bpf n'est pas egal a -1 */ vrrp_list_add(vr, &vr->ethaddr); vrrp_network_send_advertisement(vr); vrrp_thread_mutex_lock(); + vrrp_thread_mutex_lock_monitor(); if (vrrp_interface_down(vr->vr_if->if_name) == -1) { vrrp_thread_mutex_unlock(); return -1; @@@@ -73,9 +77,18 @@@@ vrrp_thread_mutex_unlock(); return -1; } - vrrp_thread_mutex_unlock(); + + /* Some NICs will reset (eg: bge/em) and wait some seconds before becoming carrier again */ + /* So we must wait for carrier */ + for (counter = 0; (counter < vr->vr_if->carrier_timeout) && (returnCode != 1); counter++) { + returnCode = vrrp_moncircuit_interface_status(vr->sd, vr->vr_if->if_name); + sleep(1); + } + + vrrp_thread_mutex_unlock_monitor(); if (vrrp_network_send_gratuitous_arp_ips(vr, &vr->ethaddr) == -1) return -1; + vrrp_thread_mutex_unlock(); if (vrrp_misc_calcul_tminterval(&vr->tm.adv_tm, vr->adv_int) == -1) return -1; vr->state = VRRP_STATE_MASTER; @@@@ -95,10 +108,13 @@@@ vrrp_state_set_backup(struct vrrp_vr * vr) { struct ether_addr ethaddr; + int returnCode = 0; + int counter = 0; vrrp_thread_mutex_lock(); vrrp_interface_vripaddr_delete(vr); ethaddr = vrrp_list_get_last(vr); + vrrp_thread_mutex_lock_monitor(); if (vrrp_interface_down(vr->vr_if->if_name) == -1) { vrrp_thread_mutex_unlock(); return -1; @@@@ -112,6 +128,15 @@@@ vrrp_thread_mutex_unlock(); return -1; } + + /* Some NICs will reset (eg: bge/em) and wait some seconds before becoming carrier again */ + /* So we must wait for carrier */ + for (counter = 0; (counter < vr->vr_if->carrier_timeout) && (returnCode != 1); counter++) { + returnCode = vrrp_moncircuit_interface_status(vr->sd, vr->vr_if->if_name); + sleep(1); + } + vrrp_thread_mutex_unlock_monitor(); + if (vrrp_network_send_gratuitous_arp_ips(vr, ðaddr) == -1) return -1; vrrp_thread_mutex_unlock(); Index: vrrp_state.h --- vrrp_state.h.orig 2003-01-30 12:50:56 +0100 +++ vrrp_state.h 2004-12-26 10:38:24 +0100 @@@@ -49,3 +49,5 @@@@ #include "vrrp_define.h" #include "vrrp_proto.h" #include "vrrp_functions.h" +#include "vrrp_moncircuit.h" +#include "vrrp_thread.h" Index: vrrp_thread.c --- vrrp_thread.c.orig 2003-01-30 12:50:56 +0100 +++ vrrp_thread.c 2004-12-26 10:38:24 +0100 @@@@ -36,7 +36,7 @@@@ #include "vrrp_thread.h" #include "vrrp_moncircuit.h" -pthread_mutex_t pth_mutex, pth_mutex_bpf; +pthread_mutex_t pth_mutex, pth_mutex_bpf, pth_mutex_monitor; void vrrp_thread_mutex_lock(void) @@@@ -70,8 +70,22 @@@@ return; } +void vrrp_thread_mutex_lock_monitor(void) +{ + pthread_mutex_lock(&pth_mutex_monitor); + + return; +} + +void vrrp_thread_mutex_unlock_monitor(void) +{ + pthread_mutex_unlock(&pth_mutex_monitor); + + return; +} + void -vrrp_thread_launch_vrrprouter(int *args) +vrrp_thread_launch_vrrprouter(void *args[2]) { struct vrrp_vr *vr = (struct vrrp_vr *)args[0]; sem_t *sem = (sem_t *)args[1]; @@@@ -116,9 +130,9 @@@@ vrrp_thread_create_vrid(struct vrrp_vr * vr) { pthread_t pth; - pthread_attr_t pth_attr = NULL; + pthread_attr_t pth_attr; sem_t sem; - int *args[2]; + void *args[2]; if (sem_init(&sem, 0, 0) == -1) { syslog(LOG_ERR, "can't initialize an unnamed semaphore [ SEM, 0, 0 ]"); @@@@ -132,8 +146,8 @@@@ syslog(LOG_ERR, "can't set thread attributes [ PTH_ATTR, PTHREAD_CREATE_DETACHED ]"); return -1; } - args[0] = (int *)vr; - args[1] = (int *)&sem; + args[0] = vr; + args[1] = &sem; if (pthread_create(&pth, &pth_attr, (void *)&vrrp_thread_launch_vrrprouter, args) != 0) { syslog(LOG_ERR, "can't create new thread [ PTH, PTH_ATTR, VRRP_THREAD_READ_SOCKET ]"); return -1; @@@@ -147,10 +161,10 @@@@ int vrrp_thread_create_moncircuit(void) { pthread_t pth; - pthread_attr_t pth_attr = NULL; + pthread_attr_t pth_attr; sem_t sem; int delay = VRRP_MONCIRCUIT_MONDELAY; - int *args[2]; + void *args[2]; if (sem_init(&sem, 0, 0) == -1) { syslog(LOG_ERR, "can't initialize an unnamed semaphore [ SEM, 0, 0 ]"); @@@@ -164,8 +178,8 @@@@ syslog(LOG_ERR, "can't set thread attributes [ PTH_ATTR, PTHREAD_CREATE_DETACHED ]"); return -1; } - args[0] = (int *)&delay; - args[1] = (int *)&sem; + args[0] = &delay; + args[1] = &sem; if (pthread_create(&pth, &pth_attr, (void *)&vrrp_moncircuit_monitor_thread, args) != 0) { syslog(LOG_ERR, "can't create new thread [ PTH, PTH_ATTR, VRRP_THREAD_READ_SOCKET ]"); return -1; Index: vrrp_thread.h --- vrrp_thread.h.orig 2003-01-30 12:50:56 +0100 +++ vrrp_thread.h 2004-12-26 10:38:24 +0100 @@@@ -46,5 +46,7 @@@@ /* Functions */ int vrrp_thread_create_moncircuit(void); +void vrrp_thread_mutex_lock_monitor(void); +void vrrp_thread_mutex_unlock_monitor(void); #endif @ 1.3 log @start vrrpd ultra-early and apply vendor patches for carrier state change handling @ text @@ 1.2 log @second attempt: seems like we have to increase the delay, too @ text @d21 366 @ 1.1 log @increase number of accepted errros during interface checks to workaround problems with longer downtimes on switch ports @ text @d3 1 a3 1 so increase this to 40sec (= 40*100000usec) because performing d8 4 a11 3 --- vrrp_define.h.orig 2004-10-14 10:08:54 +0200 +++ vrrp_define.h 2004-10-14 10:09:54 +0200 @@@@ -53,7 +53,7 @@@@ d13 2 a14 2 #define VRRP_CONF_FILE_NAME "/openpkg-dev/etc/vrrpd/vrrpd.conf" #define VRRP_MONCIRCUIT_MONDELAY 1000000 d16 2 a17 1 +#define VRRP_MONCIRCUIT_MAX_ERRORS 40 @