File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / freevrrpd / vrrp_moncircuit.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Wed Jun 14 12:01:54 2017 UTC (7 years ago) by misho
Branches: freevrrpd, MAIN
CVS tags: v1_1, HEAD
freevrrpd 1.1

    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.1.1.1 2017/06/14 12:01:54 misho 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>