Annotation of embedaddon/freevrrpd/vrrp_moncircuit.c, revision 1.1.1.1

1.1       misho       1: /*
                      2:  * Copyright (c) 2001,2002 Sebastien Petit <spe@bsdfr.org>
                      3:  *
                      4:  * Redistribution and use in source forms, with and without modification,
                      5:  * are permitted provided that the following conditions are met:
                      6:  * 1. Redistributions of source code must retain the above copyright notice,
                      7:  *    this list of conditions and the following disclaimer.
                      8:  * 2. Redistributions in binary form must reproduce the above copyright notice,
                      9:  *    this list of conditions and the following disclaimer in the documentation
                     10:  *    and/or other materials provided with the distribution. Obviously, it
                     11:  *    would be nice if you gave credit where credit is due but requiring it
                     12:  *    would be too onerous.
                     13:  * 3. All advertising materials mentioning features or use of this software
                     14:  *    must display the following acknowledgement:
                     15:  *      This product includes software developed by Sebastien Petit.
                     16:  * 4. Neither the name of its contributors may be used to endorse or promote
                     17:  *    products derived from this software without specific prior written
                     18:  *    permission.
                     19:  *
                     20:  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
                     21:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
                     22:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
                     23:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
                     24:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
                     25:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
                     26:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     27:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
                     28:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
                     29:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
                     30:  * SUCH DAMAGE.
                     31:  *
                     32:  * $Id: vrrp_moncircuit.c,v 1.6 2004/04/01 15:40:52 spe Exp $
                     33:  */
                     34: 
                     35: #include <sys/types.h>
                     36: #include <sys/socket.h>
                     37: #include <sys/ioctl.h>
                     38: #include <net/if.h>
                     39: #include <net/if_media.h>
                     40: #include <errno.h>
                     41: #include <semaphore.h>
                     42: #include <syslog.h>
                     43: #include <stdarg.h>
                     44: #include <stdio.h>
                     45: #include <string.h>
                     46: #include <unistd.h>
                     47: #include <pthread.h>
                     48: #include "vrrp_moncircuit.h"
                     49: #include "vrrp_define.h"
                     50: 
                     51: /*
                     52:  * Function that returns an integer that represent a status (carrier) of a
                     53:  * specified if_name interface transmited by argument
                     54:  * return -3: ioctl SIOCGIFMEDIA is not supported, disable moncircuits
                     55:  * return -2: interface is faulty or doesn't exist !
                     56:  * return -1: error
                     57:  * return  0: no carrier
                     58:  * return  1: ok, carrier, interface is working
                     59:  */
                     60: int vrrp_moncircuit_interface_status(int sd, char *if_name)
                     61: {
                     62:        struct ifmediareq ifmr;
                     63: 
                     64:        if (sd < 0) {
                     65:                syslog(LOG_ERR, "socket descriptor must be != -1");
                     66:                return -1;
                     67:        }
                     68:        bzero(&ifmr, sizeof(ifmr));
                     69:        strncpy(ifmr.ifm_name, if_name, sizeof(ifmr.ifm_name));
                     70: 
                     71:        if (ioctl(sd, SIOCGIFMEDIA, (caddr_t)&ifmr) < 0) {
                     72:                if (errno == EINVAL) {
                     73:                        syslog(LOG_ERR, "your NIC doesn't support SIOCGIFMEDIA ioctl: %s", strerror(errno));
                     74:                        return -3;
                     75:                }
                     76:                else
                     77:                        syslog(LOG_ERR, "cannot do ioctl, intertface is faulty: %s", strerror(errno));
                     78:                return -2;
                     79:        }
                     80: 
                     81:        if (ifmr.ifm_status & IFM_AVALID) {
                     82:                if (ifmr.ifm_status & IFM_ACTIVE)
                     83:                        return 1;
                     84:                else
                     85:                        return 0;
                     86:        }
                     87: 
                     88:        /* Interface has no carrier cable problem ? */
                     89:        return 0;
                     90: }
                     91: 
                     92: void *vrrp_moncircuit_monitor_thread(void *args)
                     93: {
                     94:        int **args2 = (int **)args;
                     95:        int delay = *args2[0];
                     96:        sem_t *sem  = (sem_t *)args2[1];
                     97:        int numvrid, numvrid2;
                     98:        int cpt;
                     99:        int sd;
                    100:        int returnCode;
                    101: 
                    102:        sd = socket(PF_INET, SOCK_DGRAM, 0);
                    103:        if (sd < 0) {
                    104:                syslog(LOG_ERR, "cannot open a DGRAM socket: %s", strerror(errno));
                    105:                pthread_exit(NULL);
                    106:        }
                    107:        sem_post(sem);
                    108:        for (;;) {
                    109:                numvrid = 0;
                    110:                while (vr_ptr[numvrid]) {
                    111:                        vrrp_thread_mutex_lock_monitor();
                    112:                        returnCode = vrrp_moncircuit_interface_status(sd, vr_ptr[numvrid]->vr_if->if_name);
                    113:                        vrrp_thread_mutex_unlock_monitor();
                    114:                        if (returnCode == -3) {
                    115:                                vr_ptr[numvrid]->useMonitoredCircuits = 0;
                    116:                                syslog(LOG_NOTICE, "monitored circuits engine disabled");
                    117:                                pthread_exit(NULL);
                    118:                        }
                    119:                        if ((returnCode == 1) && (! vr_ptr[numvrid]->fault)) {
                    120:                                if (vr_ptr[numvrid]->vr_if->nberrors < VRRP_MONCIRCUIT_MAX_ERRORS) {
                    121:                                        if (! vr_ptr[numvrid]->vr_if->alive) {
                    122:                                                vr_ptr[numvrid]->vr_if->alive = 1;
                    123:                                                syslog(LOG_ERR, "interface %s is alive again, reactivate it on VRRP", vr_ptr[numvrid]->vr_if->if_name);
                    124:                                                if (vr_ptr[numvrid]->vridsdeps) {
                    125:                                                        numvrid2 = 0;
                    126:                                                        while (vr_ptr[numvrid2]) {
                    127:                                                                cpt = 0;
                    128:                                                                while (vr_ptr[numvrid]->vridsdeps[cpt] != -1) {
                    129:                                                                        if ((vr_ptr[numvrid2]->vr_id == vr_ptr[numvrid]->vridsdeps[cpt])
                    130:                                                                            && (vr_ptr[numvrid2]->vr_if->alive == -1)) {
                    131:                                                                                vr_ptr[numvrid2]->vr_if->alive = 1;
                    132:                                                                                syslog(LOG_ERR, "VRID %d (interface %s) has been reactivated due to dependance", vr_ptr[numvrid2]->vr_id, vr_ptr[numvrid2]->vr_if->if_name);
                    133:                                                                        }
                    134:                                                                        cpt++;
                    135:                                                                }
                    136:                                                                numvrid2++;
                    137:                                                        }
                    138:                                                }
                    139:                                        }
                    140:                                        vr_ptr[numvrid]->vr_if->checksok++;
                    141:                                        if (vr_ptr[numvrid]->vr_if->checksok > vr_ptr[numvrid]->monitoredCircuitsClearErrorsCount) {
                    142:                                                vr_ptr[numvrid]->vr_if->nberrors = 0;
                    143:                                                vr_ptr[numvrid]->vr_if->checksok = 0;
                    144:                                                syslog(LOG_NOTICE, "all errors are cleared on interface %s", vr_ptr[numvrid]->vr_if->if_name);
                    145:                                        }
                    146:                                }
                    147:                                else {
                    148:                                        if (! vr_ptr[numvrid]->vr_if->reportsyslog) {
                    149:                                                syslog(LOG_ERR, "cannot reactivate interface %s, too much errors on it !", vr_ptr[numvrid]->vr_if->if_name);
                    150:                                                vr_ptr[numvrid]->vr_if->reportsyslog = 1;
                    151:                                        }
                    152:                                }
                    153:                        }
                    154:                        else {
                    155:                                if (vr_ptr[numvrid]->vr_if->alive == 1) {
                    156:                                        vr_ptr[numvrid]->vr_if->nberrors++;
                    157:                                        vr_ptr[numvrid]->vr_if->alive = 0;
                    158:                                        vr_ptr[numvrid]->vr_if->checksok = 0;
                    159:                                        syslog(LOG_ERR, "interface %s is faulty, deactivated from VRRP VRIDs", vr_ptr[numvrid]->vr_if->if_name);
                    160:                                        if (vr_ptr[numvrid]->vridsdeps) {
                    161:                                                numvrid2 = 0;
                    162:                                                while (vr_ptr[numvrid2]) {
                    163:                                                        cpt = 0;
                    164:                                                        while (vr_ptr[numvrid]->vridsdeps[cpt] != -1) {
                    165:                                                                if ((vr_ptr[numvrid2]->vr_id == vr_ptr[numvrid]->vridsdeps[cpt])
                    166:                                                                    && (vr_ptr[numvrid2]->vr_if->alive == 1)) {
                    167:                                                                        vr_ptr[numvrid2]->vr_if->alive = -1;
                    168:                                                                        vr_ptr[numvrid2]->vr_if->checksok = 0;
                    169:                                                                        syslog(LOG_ERR, "VRID %d (interface %s) has been deactivated due to dependance", vr_ptr[numvrid2]->vr_id, vr_ptr[numvrid2]->vr_if->if_name);
                    170:                                                                }
                    171:                                                                cpt++;
                    172:                                                        }
                    173:                                                        numvrid2++;
                    174:                                                }
                    175:                                        }
                    176:                                }
                    177:                        }
                    178:                        numvrid++;
                    179:                }
                    180:                sleep(delay);
                    181:        }
                    182: 
                    183:        /* Never executed */
                    184:        pthread_exit(NULL);
                    185: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>