Blame keepalived/vrrp/vrrp_track.c

Packit c22fc9
/*
Packit c22fc9
 * Soft:        Keepalived is a failover program for the LVS project
Packit c22fc9
 *              <www.linuxvirtualserver.org>. It monitor & manipulate
Packit c22fc9
 *              a loadbalanced server pool using multi-layer checks.
Packit c22fc9
 *
Packit c22fc9
 * Part:        Interface tracking framework.
Packit c22fc9
 *
Packit c22fc9
 * Author:      Alexandre Cassen, <acassen@linux-vs.org>
Packit c22fc9
 *
Packit c22fc9
 *              This program is distributed in the hope that it will be useful,
Packit c22fc9
 *              but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit c22fc9
 *              MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
Packit c22fc9
 *              See the GNU General Public License for more details.
Packit c22fc9
 *
Packit c22fc9
 *              This program is free software; you can redistribute it and/or
Packit c22fc9
 *              modify it under the terms of the GNU General Public License
Packit c22fc9
 *              as published by the Free Software Foundation; either version
Packit c22fc9
 *              2 of the License, or (at your option) any later version.
Packit c22fc9
 *
Packit c22fc9
 * Copyright (C) 2001-2017 Alexandre Cassen, <acassen@gmail.com>
Packit c22fc9
 */
Packit c22fc9
Packit c22fc9
#include "config.h"
Packit c22fc9
Packit c22fc9
#include <net/if.h>
Packit c22fc9
#include <stdlib.h>
Packit c22fc9
#include <limits.h>
Packit c22fc9
#include <stdlib.h>
Packit c22fc9
#include <errno.h>
Packit c22fc9
#include <sys/types.h>
Packit c22fc9
#include <fcntl.h>
Packit c22fc9
#include <stdio.h>
Packit c22fc9
Packit c22fc9
/* local include */
Packit Service dfccb1
#include "vrrp_track.h"
Packit c22fc9
#include "vrrp_data.h"
Packit c22fc9
#include "vrrp.h"
Packit c22fc9
#include "vrrp_sync.h"
Packit c22fc9
#include "logger.h"
Packit c22fc9
#include "memory.h"
Packit c22fc9
#include "vrrp_scheduler.h"
Packit c22fc9
#include "scheduler.h"
Packit c22fc9
#include "parser.h"
Packit Service dfccb1
#include "utils.h"
Packit Service dfccb1
#include "vrrp_notify.h"
Packit Service dfccb1
#include "bitops.h"
Packit Service dfccb1
#include "track_file.h"
Packit Service dfccb1
#ifdef _WITH_CN_PROC_
Packit Service dfccb1
#include "track_process.h"
Packit Service dfccb1
#endif
Packit c22fc9
Packit c22fc9
Packit c22fc9
/* Track interface dump */
Packit Service dfccb1
static void
Packit Service dfccb1
dump_track_if(FILE *fp, const tracked_if_t *tip)
Packit Service dfccb1
{
Packit Service dfccb1
	conf_write(fp, "     %s weight %d%s", IF_NAME(tip->ifp), tip->weight, tip->weight_reverse ? " reverse" : "");
Packit Service dfccb1
}
Packit c22fc9
void
Packit Service dfccb1
dump_track_if_list(FILE *fp, const list_head_t *l)
Packit c22fc9
{
Packit Service dfccb1
	tracked_if_t *tip;
Packit Service dfccb1
Packit Service dfccb1
	list_for_each_entry(tip, l, e_list)
Packit Service dfccb1
		dump_track_if(fp, tip);
Packit c22fc9
}
Packit c22fc9
Packit c22fc9
void
Packit Service dfccb1
free_track_if(tracked_if_t *tip)
Packit c22fc9
{
Packit Service dfccb1
	list_del_init(&tip->e_list);
Packit c22fc9
	FREE(tip);
Packit c22fc9
}
Packit c22fc9
void
Packit Service dfccb1
free_track_if_list(list_head_t *l)
Packit c22fc9
{
Packit Service dfccb1
	tracked_if_t *tip, *tip_tmp;
Packit c22fc9
Packit Service dfccb1
	list_for_each_entry_safe(tip, tip_tmp, l, e_list)
Packit Service dfccb1
		free_track_if(tip);
Packit c22fc9
}
Packit c22fc9
Packit c22fc9
void
Packit Service dfccb1
alloc_track_if(const char *name, list_head_t *l, const vector_t *strvec)
Packit c22fc9
{
Packit c22fc9
	interface_t *ifp;
Packit c22fc9
	tracked_if_t *tip;
Packit c22fc9
	int weight = 0;
Packit Service dfccb1
	const char *tracked = strvec_slot(strvec, 0);
Packit Service dfccb1
	bool reverse = false;
Packit c22fc9
Packit c22fc9
	ifp = if_get_by_ifname(tracked, IF_CREATE_IF_DYNAMIC);
Packit c22fc9
	if (!ifp) {
Packit Service dfccb1
		report_config_error(CONFIG_GENERAL_ERROR, "(%s) tracked interface %s doesn't exist"
Packit Service dfccb1
							, name, tracked);
Packit c22fc9
		return;
Packit c22fc9
	}
Packit c22fc9
Packit Service dfccb1
	/* Check this vrrp isn't already tracking the i/f */
Packit Service dfccb1
	list_for_each_entry(tip, l, e_list) {
Packit c22fc9
		if (tip->ifp == ifp) {
Packit Service dfccb1
			report_config_error(CONFIG_GENERAL_ERROR, "(%s) duplicate track_interface %s - ignoring"
Packit Service dfccb1
								, name, tracked);
Packit c22fc9
			return;
Packit c22fc9
		}
Packit c22fc9
	}
Packit c22fc9
Packit Service dfccb1
	if (vector_size(strvec) >= 2) {
Packit Service dfccb1
		if (strcmp(strvec_slot(strvec, 1), "weight")) {
Packit Service dfccb1
			report_config_error(CONFIG_GENERAL_ERROR, "(%s) unknown track_interface %s"
Packit Service dfccb1
								  " option %s - ignoring"
Packit Service dfccb1
								, name, tracked, strvec_slot(strvec, 1));
Packit Service dfccb1
			return;
Packit Service dfccb1
		}
Packit Service dfccb1
Packit Service dfccb1
		if (vector_size(strvec) == 2) {
Packit Service dfccb1
			report_config_error(CONFIG_GENERAL_ERROR, "(%s) weight without value specified"
Packit Service dfccb1
								  " for track_interface %s - ignoring"
Packit Service dfccb1
								, name, tracked);
Packit Service dfccb1
			return;
Packit Service dfccb1
		}
Packit Service dfccb1
Packit c22fc9
		if (!read_int_strvec(strvec, 2, &weight, -254, 254, true)) {
Packit Service dfccb1
			report_config_error(CONFIG_GENERAL_ERROR, "(%s) weight %s for %s must be"
Packit Service dfccb1
								  " between [-253..253] inclusive. Ignoring..."
Packit Service dfccb1
								, name, strvec_slot(strvec, 2), tracked);
Packit c22fc9
			weight = 0;
Packit c22fc9
		}
Packit c22fc9
		else if (weight == -254 || weight == 254) {
Packit c22fc9
			/* This check can be removed once users have migrated away from +/-254 */
Packit Service dfccb1
			report_config_error(CONFIG_GENERAL_ERROR, "(%s) weight for %s cannot be +/-254."
Packit Service dfccb1
								  " Setting to +/-253"
Packit Service dfccb1
								, name, tracked);
Packit c22fc9
			weight = weight == -254 ? -253 : 253;
Packit c22fc9
		}
Packit Service dfccb1
Packit Service dfccb1
		if (vector_size(strvec) >= 4) {
Packit Service dfccb1
			if (!strcmp(strvec_slot(strvec, 3), "reverse"))
Packit Service dfccb1
				reverse = true;
Packit Service dfccb1
			else
Packit Service dfccb1
				report_config_error(CONFIG_GENERAL_ERROR, "(%s) unknown track_interace %s"
Packit Service dfccb1
									  " weight option %s - ignoring"
Packit Service dfccb1
									, name, tracked, strvec_slot(strvec, 3));
Packit Service dfccb1
		}
Packit c22fc9
	}
Packit c22fc9
Packit c22fc9
	tip	    = (tracked_if_t *) MALLOC(sizeof(tracked_if_t));
Packit Service dfccb1
	INIT_LIST_HEAD(&tip->e_list);
Packit c22fc9
	tip->ifp    = ifp;
Packit c22fc9
	tip->weight = weight;
Packit Service dfccb1
	tip->weight_reverse = reverse;
Packit c22fc9
Packit Service dfccb1
	list_add_tail(&tip->e_list, l);
Packit c22fc9
}
Packit c22fc9
Packit Service dfccb1
vrrp_script_t * __attribute__ ((pure))
Packit Service dfccb1
find_script_by_name(const char *name)
Packit c22fc9
{
Packit c22fc9
	vrrp_script_t *scr;
Packit c22fc9
Packit Service dfccb1
	list_for_each_entry(scr, &vrrp_data->vrrp_script, e_list) {
Packit c22fc9
		if (!strcmp(scr->sname, name))
Packit c22fc9
			return scr;
Packit c22fc9
	}
Packit Service dfccb1
Packit c22fc9
	return NULL;
Packit c22fc9
}
Packit c22fc9
Packit c22fc9
/* Track script dump */
Packit Service dfccb1
static void
Packit Service dfccb1
dump_track_script(FILE *fp, const tracked_sc_t *tsc)
Packit c22fc9
{
Packit Service dfccb1
	conf_write(fp, "     %s weight %d%s", tsc->scr->sname, tsc->weight, tsc->weight_reverse ? " reverse" : "");
Packit c22fc9
}
Packit Service dfccb1
void
Packit Service dfccb1
dump_track_script_list(FILE *fp, const list_head_t *l)
Packit Service dfccb1
{
Packit Service dfccb1
	tracked_sc_t *tsc;
Packit c22fc9
Packit Service dfccb1
	list_for_each_entry(tsc, l, e_list)
Packit Service dfccb1
		dump_track_script(fp, tsc);
Packit Service dfccb1
}
Packit c22fc9
void
Packit Service dfccb1
free_track_script(tracked_sc_t *tsc)
Packit c22fc9
{
Packit Service dfccb1
	list_del_init(&tsc->e_list);
Packit c22fc9
	FREE(tsc);
Packit c22fc9
}
Packit Service dfccb1
void
Packit Service dfccb1
free_track_script_list(list_head_t *l)
Packit Service dfccb1
{
Packit Service dfccb1
	tracked_sc_t *tsc, *tsc_tmp;
Packit Service dfccb1
Packit Service dfccb1
	list_for_each_entry_safe(tsc, tsc_tmp, l, e_list)
Packit Service dfccb1
		free_track_script(tsc);
Packit Service dfccb1
}
Packit c22fc9
Packit c22fc9
void
Packit Service dfccb1
alloc_track_script(const char *name, list_head_t *l, const vector_t *strvec)
Packit c22fc9
{
Packit c22fc9
	vrrp_script_t *vsc;
Packit c22fc9
	tracked_sc_t *tsc;
Packit c22fc9
	int weight;
Packit Service dfccb1
	const char *tracked = strvec_slot(strvec, 0);
Packit c22fc9
	tracked_sc_t *etsc;
Packit Service dfccb1
	bool reverse;
Packit c22fc9
Packit c22fc9
	vsc = find_script_by_name(tracked);
Packit c22fc9
Packit c22fc9
	/* Ignoring if no script found */
Packit c22fc9
	if (!vsc) {
Packit Service dfccb1
		report_config_error(CONFIG_GENERAL_ERROR, "(%s) track script %s not found, ignoring..."
Packit Service dfccb1
							, name, tracked);
Packit c22fc9
		return;
Packit c22fc9
	}
Packit c22fc9
Packit Service dfccb1
	/* Check this vrrp isn't already tracking the script */
Packit Service dfccb1
	list_for_each_entry(etsc, l, e_list) {
Packit Service dfccb1
		if (etsc->scr == vsc) {
Packit Service dfccb1
			report_config_error(CONFIG_GENERAL_ERROR, "(%s) duplicate track_script %s - ignoring"
Packit Service dfccb1
								, name, tracked);
Packit Service dfccb1
			return;
Packit c22fc9
		}
Packit c22fc9
	}
Packit c22fc9
Packit c22fc9
	/* default weight */
Packit c22fc9
	weight = vsc->weight;
Packit Service dfccb1
	reverse = vsc->weight_reverse;
Packit c22fc9
Packit Service dfccb1
	if (vector_size(strvec) >= 2) {
Packit Service dfccb1
		if (strcmp(strvec_slot(strvec, 1), "weight")) {
Packit Service dfccb1
			report_config_error(CONFIG_GENERAL_ERROR, "(%s) unknown track script option %s - ignoring"
Packit Service dfccb1
								, name, strvec_slot(strvec, 1));
Packit Service dfccb1
			return;
Packit c22fc9
		}
Packit c22fc9
Packit Service dfccb1
		if (vector_size(strvec) == 2) {
Packit Service dfccb1
			report_config_error(CONFIG_GENERAL_ERROR, "(%s) weight without value specified for"
Packit Service dfccb1
								  " track script %s - ignoring"
Packit Service dfccb1
								, name, tracked);
Packit Service dfccb1
			return;
Packit c22fc9
		}
Packit c22fc9
Packit c22fc9
		if (!read_int_strvec(strvec, 2, &weight, -254, 254, true)) {
Packit c22fc9
			weight = vsc->weight;
Packit Service dfccb1
			report_config_error(CONFIG_GENERAL_ERROR, "(%s) track script %s: weight must be"
Packit Service dfccb1
								  " between [-253..253] inclusive, ignoring..."
Packit Service dfccb1
								, name, tracked);
Packit c22fc9
		}
Packit c22fc9
		else if (weight == -254 || weight == 254) {
Packit c22fc9
			/* This check can be removed once users have migrated away from +/-254 */
Packit Service dfccb1
			report_config_error(CONFIG_GENERAL_ERROR, "(%s) weight for %s cannot be +/-254."
Packit Service dfccb1
								  " Setting to +/-253"
Packit Service dfccb1
								, name, tracked);
Packit c22fc9
			weight = weight == -254 ? -253 : 253;
Packit c22fc9
		}
Packit Service dfccb1
Packit Service dfccb1
		if (vector_size(strvec) >= 4) {
Packit Service dfccb1
			if (!strcmp(strvec_slot(strvec, 3), "reverse"))
Packit Service dfccb1
				reverse = true;
Packit Service dfccb1
			else if (!strcmp(strvec_slot(strvec, 3), "noreverse"))
Packit Service dfccb1
				reverse = false;
Packit Service dfccb1
			else
Packit Service dfccb1
				report_config_error(CONFIG_GENERAL_ERROR, "(%s) unknown track_script %s"
Packit Service dfccb1
									  " weight option %s - ignoring"
Packit Service dfccb1
									, name, tracked, strvec_slot(strvec, 3));
Packit Service dfccb1
		}
Packit c22fc9
	}
Packit c22fc9
Packit c22fc9
	tsc	    = (tracked_sc_t *) MALLOC(sizeof(tracked_sc_t));
Packit Service dfccb1
	INIT_LIST_HEAD(&tsc->e_list);
Packit c22fc9
	tsc->scr    = vsc;
Packit c22fc9
	tsc->weight = weight;
Packit Service dfccb1
	tsc->weight_reverse = reverse;
Packit c22fc9
	vsc->init_state = SCRIPT_INIT_STATE_INIT;
Packit Service dfccb1
	list_add_tail(&tsc->e_list, l);
Packit c22fc9
}
Packit c22fc9
Packit Service dfccb1
#ifdef _WITH_CN_PROC_
Packit Service dfccb1
static vrrp_tracked_process_t * __attribute__ ((pure))
Packit Service dfccb1
find_tracked_process_by_name(const char *name)
Packit c22fc9
{
Packit Service dfccb1
	vrrp_tracked_process_t *process;
Packit c22fc9
Packit Service dfccb1
	list_for_each_entry(process, &vrrp_data->vrrp_track_processes, e_list) {
Packit Service dfccb1
		if (!strcmp(process->pname, name))
Packit Service dfccb1
			return process;
Packit c22fc9
	}
Packit c22fc9
	return NULL;
Packit c22fc9
}
Packit c22fc9
Packit Service dfccb1
/* Track process dump */
Packit Service dfccb1
static void
Packit Service dfccb1
dump_track_process(FILE *fp, const tracked_process_t *tprocess)
Packit Service dfccb1
{
Packit Service dfccb1
	conf_write(fp, "     %s, weight %d%s", tprocess->process->pname
Packit Service dfccb1
					     , tprocess->weight, tprocess->weight_reverse ? " reverse" : "");
Packit Service dfccb1
}
Packit c22fc9
void
Packit Service dfccb1
dump_track_process_list(FILE *fp, const list_head_t *l)
Packit c22fc9
{
Packit Service dfccb1
	tracked_process_t *tprocess;
Packit Service dfccb1
Packit Service dfccb1
	list_for_each_entry(tprocess, l, e_list)
Packit Service dfccb1
		dump_track_process(fp, tprocess);
Packit c22fc9
}
Packit c22fc9
Packit c22fc9
void
Packit Service dfccb1
free_track_process_list(list_head_t *l)
Packit c22fc9
{
Packit Service dfccb1
	tracked_process_t *tprocess, *tprocess_tmp;
Packit Service dfccb1
Packit Service dfccb1
	list_for_each_entry_safe(tprocess, tprocess_tmp, l, e_list)
Packit Service dfccb1
		FREE(tprocess);
Packit c22fc9
}
Packit c22fc9
Packit c22fc9
void
Packit Service dfccb1
alloc_track_process(const char *name, list_head_t *l, const vector_t *strvec)
Packit c22fc9
{
Packit Service dfccb1
	vrrp_tracked_process_t *vsp;
Packit Service dfccb1
	const char *tracked = strvec_slot(strvec, 0);
Packit Service dfccb1
	tracked_process_t *tprocess;
Packit c22fc9
	int weight;
Packit Service dfccb1
	bool reverse;
Packit c22fc9
Packit Service dfccb1
	vsp = find_tracked_process_by_name(tracked);
Packit c22fc9
Packit Service dfccb1
	/* Ignoring if no process found */
Packit Service dfccb1
	if (!vsp) {
Packit Service dfccb1
		if (proc_events_not_supported)
Packit Service dfccb1
			report_config_error(CONFIG_GENERAL_ERROR, "(%s) track process not supported by kernel"
Packit Service dfccb1
								, name);
Packit Service dfccb1
		else
Packit Service dfccb1
			report_config_error(CONFIG_GENERAL_ERROR, "(%s) track process %s not found, ignoring..."
Packit Service dfccb1
								, name, tracked);
Packit c22fc9
		return;
Packit c22fc9
	}
Packit c22fc9
Packit Service dfccb1
	/* Check this vrrp isn't already tracking the process */
Packit Service dfccb1
	list_for_each_entry(tprocess, l, e_list) {
Packit Service dfccb1
		if (tprocess->process == vsp) {
Packit Service dfccb1
			report_config_error(CONFIG_GENERAL_ERROR, "(%s) duplicate track_process %s - ignoring"
Packit Service dfccb1
								, name, tracked);
Packit Service dfccb1
			return;
Packit c22fc9
		}
Packit c22fc9
	}
Packit c22fc9
Packit Service dfccb1
	weight = vsp->weight;
Packit Service dfccb1
	reverse = vsp->weight_reverse;
Packit c22fc9
	if (vector_size(strvec) >= 2) {
Packit c22fc9
		if (strcmp(strvec_slot(strvec, 1), "weight")) {
Packit Service dfccb1
			report_config_error(CONFIG_GENERAL_ERROR, "(%s) unknown track process option %s - ignoring"
Packit Service dfccb1
								, name, strvec_slot(strvec, 1));
Packit c22fc9
			return;
Packit c22fc9
		}
Packit Service dfccb1
Packit Service dfccb1
		if (vector_size(strvec) == 2) {
Packit Service dfccb1
			report_config_error(CONFIG_GENERAL_ERROR, "(%s) weight without value specified for"
Packit Service dfccb1
								  " track process %s - ignoring"
Packit Service dfccb1
								, name, tracked);
Packit c22fc9
			return;
Packit c22fc9
		}
Packit c22fc9
Packit Service dfccb1
		if (!read_int_strvec(strvec, 2, &weight, -254, 254, true)) {
Packit Service dfccb1
			report_config_error(CONFIG_GENERAL_ERROR, "(%s) weight for track process %s must be in "
Packit Service dfccb1
								  "[-254..254] inclusive. Ignoring..."
Packit Service dfccb1
								, name, tracked);
Packit Service dfccb1
			weight = vsp->weight;
Packit c22fc9
		}
Packit c22fc9
Packit Service dfccb1
		if (vector_size(strvec) >= 4) {
Packit Service dfccb1
			if (!strcmp(strvec_slot(strvec, 3), "reverse"))
Packit Service dfccb1
				reverse = true;
Packit Service dfccb1
			else if (!strcmp(strvec_slot(strvec, 3), "noreverse"))
Packit Service dfccb1
				reverse = false;
Packit Service dfccb1
			else
Packit Service dfccb1
				report_config_error(CONFIG_GENERAL_ERROR, "(%s) unknown track_process %s weight"
Packit Service dfccb1
									  " option %s - ignoring"
Packit Service dfccb1
									, name, tracked, strvec_slot(strvec, 3));
Packit c22fc9
		}
Packit c22fc9
	}
Packit c22fc9
Packit Service dfccb1
	PMALLOC(tprocess);
Packit Service dfccb1
	INIT_LIST_HEAD(&tprocess->e_list);
Packit Service dfccb1
	tprocess->process = vsp;
Packit Service dfccb1
	tprocess->weight = weight;
Packit Service dfccb1
	tprocess->weight_reverse = reverse;
Packit Service dfccb1
	list_add_tail(&tprocess->e_list, l);
Packit c22fc9
}
Packit Service dfccb1
#endif
Packit c22fc9
Packit c22fc9
#ifdef _WITH_BFD_
Packit Service dfccb1
/* VRRP Track bfd related */
Packit Service dfccb1
vrrp_tracked_bfd_t * __attribute__ ((pure))
Packit c22fc9
find_vrrp_tracked_bfd_by_name(const char *name)
Packit c22fc9
{
Packit c22fc9
	vrrp_tracked_bfd_t *bfd;
Packit c22fc9
Packit Service dfccb1
	list_for_each_entry(bfd, &vrrp_data->vrrp_track_bfds, e_list) {
Packit c22fc9
		if (!strcmp(bfd->bname, name))
Packit c22fc9
			return bfd;
Packit c22fc9
	}
Packit c22fc9
	return NULL;
Packit c22fc9
}
Packit c22fc9
Packit c22fc9
void
Packit Service dfccb1
alloc_vrrp_tracked_bfd(const char *name, list_head_t *l)
Packit c22fc9
{
Packit Service dfccb1
	vrrp_tracked_bfd_t *tbfd;
Packit Service dfccb1
Packit Service dfccb1
	if (strlen(name) >= BFD_INAME_MAX) {
Packit Service dfccb1
		report_config_error(CONFIG_GENERAL_ERROR, "BFD name %s too long", name);
Packit Service dfccb1
		skip_block(true);
Packit Service dfccb1
		return;
Packit Service dfccb1
	}
Packit Service dfccb1
Packit Service dfccb1
	list_for_each_entry(tbfd, l, e_list) {
Packit Service dfccb1
		if (!strcmp(name, tbfd->bname)) {
Packit Service dfccb1
			report_config_error(CONFIG_GENERAL_ERROR, "BFD %s already specified", name);
Packit Service dfccb1
			skip_block(true);
Packit Service dfccb1
			return;
Packit Service dfccb1
		}
Packit Service dfccb1
	}
Packit Service dfccb1
Packit Service dfccb1
	PMALLOC(tbfd);
Packit Service dfccb1
	INIT_LIST_HEAD(&tbfd->e_list);
Packit Service dfccb1
	strncpy(tbfd->bname, name, BFD_INAME_MAX-1); /* Not really need, but... */
Packit Service dfccb1
	tbfd->weight = 0;
Packit Service dfccb1
	tbfd->weight_reverse = false;
Packit Service dfccb1
	tbfd->bfd_up = false;
Packit Service dfccb1
	INIT_LIST_HEAD(&tbfd->tracking_vrrp);
Packit Service dfccb1
	list_add_tail(&tbfd->e_list, l);
Packit c22fc9
}
Packit c22fc9
Packit Service dfccb1
/* Track bfd related */
Packit Service dfccb1
static void
Packit Service dfccb1
dump_tracked_bfd(FILE *fp, const tracked_bfd_t *tbfd)
Packit c22fc9
{
Packit Service dfccb1
	conf_write(fp, "     %s: weight %d%s", tbfd->bfd->bname, tbfd->weight, tbfd->weight_reverse ? " reverse" : "");
Packit c22fc9
}
Packit c22fc9
void
Packit Service dfccb1
dump_tracked_bfd_list(FILE *fp, const list_head_t *l)
Packit c22fc9
{
Packit c22fc9
	tracked_bfd_t *tbfd;
Packit c22fc9
Packit Service dfccb1
	list_for_each_entry(tbfd, l, e_list)
Packit Service dfccb1
		dump_tracked_bfd(fp, tbfd);
Packit Service dfccb1
}
Packit c22fc9
Packit Service dfccb1
void
Packit Service dfccb1
free_track_bfd(tracked_bfd_t *tbfd)
Packit Service dfccb1
{
Packit Service dfccb1
	list_del_init(&tbfd->e_list);
Packit Service dfccb1
	FREE(tbfd);
Packit Service dfccb1
}
Packit Service dfccb1
void
Packit Service dfccb1
free_track_bfd_list(list_head_t *l)
Packit Service dfccb1
{
Packit Service dfccb1
	tracked_bfd_t *tbfd, *tbfd_tmp;
Packit c22fc9
Packit Service dfccb1
	list_for_each_entry_safe(tbfd, tbfd_tmp, l, e_list)
Packit Service dfccb1
		free_track_bfd(tbfd);
Packit c22fc9
}
Packit c22fc9
Packit c22fc9
void
Packit Service dfccb1
alloc_track_bfd(const char *name, list_head_t *l, const vector_t *strvec)
Packit c22fc9
{
Packit c22fc9
	vrrp_tracked_bfd_t *vtb;
Packit c22fc9
	tracked_bfd_t *tbfd;
Packit Service dfccb1
	const char *tracked = strvec_slot(strvec, 0);
Packit c22fc9
	tracked_bfd_t *etbfd;
Packit c22fc9
	int weight;
Packit Service dfccb1
	bool reverse = false;
Packit c22fc9
Packit c22fc9
	vtb = find_vrrp_tracked_bfd_by_name(tracked);
Packit c22fc9
Packit c22fc9
	/* Ignoring if no bfd found */
Packit c22fc9
	if (!vtb) {
Packit Service dfccb1
		report_config_error(CONFIG_GENERAL_ERROR, "(%s) track bfd %s not found, ignoring..."
Packit Service dfccb1
							, name, tracked);
Packit c22fc9
		return;
Packit c22fc9
	}
Packit c22fc9
Packit Service dfccb1
	/* Check this vrrp isn't already tracking the bfd */
Packit Service dfccb1
	list_for_each_entry(etbfd, l, e_list) {
Packit c22fc9
		if (etbfd->bfd == vtb) {
Packit Service dfccb1
			report_config_error(CONFIG_GENERAL_ERROR, "(%s) duplicate track_bfd %s - ignoring"
Packit Service dfccb1
								, name, tracked);
Packit c22fc9
			return;
Packit c22fc9
		}
Packit c22fc9
	}
Packit c22fc9
Packit c22fc9
	weight = vtb->weight;
Packit Service dfccb1
	reverse = vtb->weight_reverse;
Packit c22fc9
	if (vector_size(strvec) >= 2) {
Packit c22fc9
		if (strcmp(strvec_slot(strvec, 1), "weight")) {
Packit Service dfccb1
			report_config_error(CONFIG_GENERAL_ERROR, "(%s) unknown track bfd %s option %s - ignoring"
Packit Service dfccb1
								, name, tracked, strvec_slot(strvec, 1));
Packit c22fc9
			return;
Packit c22fc9
		}
Packit Service dfccb1
Packit Service dfccb1
		if (vector_size(strvec) == 2) {
Packit Service dfccb1
			report_config_error(CONFIG_GENERAL_ERROR, "(%s) weight without value specified"
Packit Service dfccb1
								  " for track bfd %s - ignoring"
Packit Service dfccb1
								, name, tracked);
Packit c22fc9
			return;
Packit c22fc9
		}
Packit Service dfccb1
Packit Service dfccb1
		if (!read_int_strvec(strvec, 2, &weight, -253, 253, true)) {
Packit Service dfccb1
			report_config_error(CONFIG_GENERAL_ERROR, "(%s) weight for track bfd %s must be in "
Packit Service dfccb1
								  "[-253..253] inclusive. Ignoring..."
Packit Service dfccb1
								, name, tracked);
Packit Service dfccb1
			weight = vtb->weight;
Packit Service dfccb1
		}
Packit Service dfccb1
Packit Service dfccb1
		if (vector_size(strvec) >= 4) {
Packit Service dfccb1
			if (!strcmp(strvec_slot(strvec, 3), "reverse"))
Packit Service dfccb1
				reverse = true;
Packit Service dfccb1
			else if (!strcmp(strvec_slot(strvec, 3), "noreverse"))
Packit Service dfccb1
				reverse = false;
Packit Service dfccb1
			else {
Packit Service dfccb1
				report_config_error(CONFIG_GENERAL_ERROR, "(%s) unknown track bfd %s weight"
Packit Service dfccb1
									  " option %s - ignoring"
Packit Service dfccb1
									, name, tracked, strvec_slot(strvec, 3));
Packit Service dfccb1
				return;
Packit Service dfccb1
			}
Packit Service dfccb1
		}
Packit c22fc9
	}
Packit c22fc9
Packit Service dfccb1
	PMALLOC(tbfd);
Packit Service dfccb1
	INIT_LIST_HEAD(&tbfd->e_list);
Packit c22fc9
	tbfd->bfd = vtb;
Packit c22fc9
	tbfd->weight = weight;
Packit Service dfccb1
	tbfd->weight_reverse = reverse;
Packit Service dfccb1
	list_add_tail(&tbfd->e_list, l);
Packit c22fc9
}
Packit c22fc9
#endif
Packit c22fc9
Packit c22fc9
void
Packit c22fc9
down_instance(vrrp_t *vrrp)
Packit c22fc9
{
Packit c22fc9
	if (vrrp->num_script_if_fault++ == 0 || vrrp->state == VRRP_STATE_INIT) {
Packit c22fc9
		vrrp->wantstate = VRRP_STATE_FAULT;
Packit c22fc9
		if (vrrp->state == VRRP_STATE_MAST)
Packit c22fc9
			vrrp_state_leave_master(vrrp, true);
Packit c22fc9
		else
Packit c22fc9
			vrrp_state_leave_fault(vrrp);
Packit c22fc9
Packit c22fc9
		if (vrrp->sync && vrrp->sync->num_member_fault++ == 0)
Packit c22fc9
			vrrp_sync_fault(vrrp);
Packit c22fc9
	}
Packit c22fc9
}
Packit c22fc9
Packit c22fc9
/* Set effective priorty, issue message on changes */
Packit c22fc9
void
Packit c22fc9
vrrp_set_effective_priority(vrrp_t *vrrp)
Packit c22fc9
{
Packit c22fc9
	uint8_t new_prio;
Packit c22fc9
	uint32_t old_down_timer;
Packit c22fc9
Packit c22fc9
	/* Don't change priority if address owner */
Packit c22fc9
	if (vrrp->base_priority == VRRP_PRIO_OWNER)
Packit c22fc9
		return;
Packit c22fc9
Packit c22fc9
	if (vrrp->total_priority < 1)
Packit c22fc9
		new_prio = 1;
Packit c22fc9
	else if (vrrp->total_priority >= VRRP_PRIO_OWNER)
Packit c22fc9
		new_prio = VRRP_PRIO_OWNER - 1;
Packit c22fc9
	else
Packit c22fc9
		new_prio = (uint8_t)vrrp->total_priority;
Packit c22fc9
Packit c22fc9
	if (vrrp->effective_priority == new_prio)
Packit c22fc9
		return;
Packit c22fc9
Packit c22fc9
	log_message(LOG_INFO, "(%s) Changing effective priority from %d to %d",
Packit c22fc9
		    vrrp->iname, vrrp->effective_priority, new_prio);
Packit c22fc9
Packit c22fc9
	vrrp->effective_priority = new_prio;
Packit c22fc9
	old_down_timer = vrrp->ms_down_timer;
Packit c22fc9
	vrrp->ms_down_timer = 3 * vrrp->master_adver_int + VRRP_TIMER_SKEW(vrrp);
Packit c22fc9
Packit c22fc9
	if (vrrp->state == VRRP_STATE_BACK) {
Packit c22fc9
		if (old_down_timer < vrrp->ms_down_timer)
Packit c22fc9
			vrrp->sands = timer_add_long(vrrp->sands, vrrp->ms_down_timer - old_down_timer);
Packit c22fc9
		else
Packit c22fc9
			vrrp->sands = timer_sub_long(vrrp->sands, old_down_timer - vrrp->ms_down_timer);
Packit c22fc9
		vrrp_thread_requeue_read(vrrp);
Packit c22fc9
	}
Packit Service dfccb1
Packit Service dfccb1
	if (vrrp->notify_priority_changes)
Packit Service dfccb1
		send_instance_priority_notifies(vrrp);
Packit c22fc9
}
Packit c22fc9
Packit c22fc9
static void
Packit Service dfccb1
process_script_update_priority(int weight, int multiplier, vrrp_script_t *vscript, bool script_ok, vrrp_t *vrrp)
Packit c22fc9
{
Packit c22fc9
	bool instance_left_init = false;
Packit c22fc9
Packit c22fc9
	if (!weight) {
Packit c22fc9
		if (vscript->init_state == SCRIPT_INIT_STATE_INIT) {
Packit c22fc9
			/* We need to adjust the number of scripts in init state */
Packit c22fc9
			if (!--vrrp->num_script_init) {
Packit c22fc9
				instance_left_init = true;
Packit c22fc9
				if (vrrp->sync)
Packit c22fc9
					vrrp->sync->num_member_init--;
Packit c22fc9
			}
Packit c22fc9
		}
Packit c22fc9
Packit Service dfccb1
		if (script_ok != (multiplier == 1)) {
Packit c22fc9
			/* The instance needs to go down */
Packit c22fc9
			down_instance(vrrp);
Packit c22fc9
		} else if (!vrrp->num_script_init &&
Packit c22fc9
			   (!vrrp->sync || !vrrp->sync->num_member_init)) {
Packit c22fc9
			/* The instance can come up */
Packit c22fc9
			try_up_instance(vrrp, instance_left_init);  // Set want_state = BACKUP/MASTER, and check i/fs and sync groups
Packit c22fc9
		}
Packit c22fc9
		return;
Packit c22fc9
	}
Packit c22fc9
Packit c22fc9
	if (vscript->init_state == SCRIPT_INIT_STATE_INIT) {
Packit c22fc9
		/* If the script hasn't previously exited, we need
Packit c22fc9
		   to only adjust the priority if the state the script
Packit c22fc9
		   is now in causes an adjustment to the priority */
Packit c22fc9
		if (script_ok) {
Packit c22fc9
			if (weight > 0)
Packit Service dfccb1
				vrrp->total_priority += weight * multiplier;
Packit c22fc9
		} else {
Packit c22fc9
			if (weight < 0)
Packit Service dfccb1
				vrrp->total_priority += weight * multiplier;
Packit c22fc9
		}
Packit c22fc9
	} else {
Packit c22fc9
		if (script_ok)
Packit Service dfccb1
			vrrp->total_priority += abs(weight) * multiplier;
Packit c22fc9
		else
Packit Service dfccb1
			vrrp->total_priority -= abs(weight) * multiplier;
Packit c22fc9
	}
Packit c22fc9
Packit c22fc9
	vrrp_set_effective_priority(vrrp);
Packit c22fc9
}
Packit c22fc9
Packit c22fc9
void
Packit c22fc9
update_script_priorities(vrrp_script_t *vscript, bool script_ok)
Packit c22fc9
{
Packit Service dfccb1
	tracking_obj_t* top;
Packit c22fc9
	vrrp_t *vrrp;
Packit c22fc9
Packit c22fc9
	/* First process the vrrp instances tracking the script */
Packit Service dfccb1
	list_for_each_entry(top, &vscript->tracking_vrrp, e_list) {
Packit Service dfccb1
		vrrp = top->obj.vrrp;
Packit Service dfccb1
		process_script_update_priority(top->weight, top->weight_multiplier, vscript, script_ok, vrrp);
Packit c22fc9
	}
Packit c22fc9
}
Packit c22fc9
Packit c22fc9
static void
Packit c22fc9
initialise_track_script_state(tracked_sc_t *tsc, vrrp_t *vrrp)
Packit c22fc9
{
Packit c22fc9
	if (!tsc->weight) {
Packit c22fc9
		if (tsc->scr->init_state == SCRIPT_INIT_STATE_INIT)
Packit c22fc9
			vrrp->num_script_init++;
Packit c22fc9
		else if (tsc->scr->init_state == SCRIPT_INIT_STATE_FAILED ||
Packit c22fc9
			 (tsc->scr->result >= 0 && tsc->scr->result < tsc->scr->rise)) {
Packit c22fc9
			/* The script is in fault state */
Packit c22fc9
			vrrp->num_script_if_fault++;
Packit Service dfccb1
			log_message(LOG_INFO, "(%s): entering FAULT state due to script %s", vrrp->iname, tsc->scr->sname);
Packit c22fc9
			vrrp->state = VRRP_STATE_FAULT;
Packit c22fc9
		}
Packit c22fc9
		return;
Packit c22fc9
	}
Packit c22fc9
Packit c22fc9
	/* Don't change effective priority if address owner */
Packit c22fc9
	if (vrrp->base_priority == VRRP_PRIO_OWNER)
Packit c22fc9
		return;
Packit c22fc9
Packit c22fc9
	if (tsc->scr->init_state != SCRIPT_INIT_STATE_INIT)
Packit c22fc9
	{
Packit c22fc9
		if (tsc->scr->result >= tsc->scr->rise) {
Packit c22fc9
			if (tsc->weight > 0)
Packit c22fc9
				vrrp->total_priority += tsc->weight;
Packit c22fc9
		} else {
Packit c22fc9
			if (tsc->weight < 0)
Packit c22fc9
				vrrp->total_priority += tsc->weight;
Packit c22fc9
		}
Packit c22fc9
	}
Packit c22fc9
}
Packit c22fc9
Packit c22fc9
#ifdef _WITH_BFD_
Packit c22fc9
static void
Packit c22fc9
initialise_track_bfd_state(tracked_bfd_t *tbfd, vrrp_t *vrrp)
Packit c22fc9
{
Packit Service dfccb1
	int multiplier = tbfd->weight_reverse ? -1 : 1;
Packit Service dfccb1
Packit Service dfccb1
	if (tbfd->weight) {
Packit Service dfccb1
		if (tbfd->bfd->bfd_up) {
Packit Service dfccb1
			if (tbfd->weight > 0)
Packit Service dfccb1
				vrrp->total_priority += tbfd->weight * multiplier;
Packit Service dfccb1
		} else {
Packit Service dfccb1
			if (tbfd->weight < 0)
Packit Service dfccb1
				vrrp->total_priority += tbfd->weight * multiplier;
Packit Service dfccb1
			else if (!tbfd->weight) {
Packit Service dfccb1
				vrrp->num_script_if_fault++;
Packit Service dfccb1
				vrrp->state = VRRP_STATE_FAULT;
Packit Service dfccb1
			}
Packit c22fc9
		}
Packit Service dfccb1
	} else if (tbfd->bfd->bfd_up == tbfd->weight_reverse) {
Packit Service dfccb1
		vrrp->num_script_if_fault++;
Packit Service dfccb1
		vrrp->state = VRRP_STATE_FAULT;
Packit c22fc9
	}
Packit c22fc9
}
Packit c22fc9
#endif
Packit c22fc9
Packit c22fc9
static void
Packit c22fc9
initialise_interface_tracking_priorities(void)
Packit c22fc9
{
Packit Service dfccb1
	tracking_obj_t *top;
Packit Service dfccb1
	vrrp_t *vrrp;
Packit c22fc9
	interface_t *ifp;
Packit Service dfccb1
	list_head_t *ifq;
Packit c22fc9
Packit Service dfccb1
	ifq = get_interface_queue();
Packit Service dfccb1
	list_for_each_entry(ifp, ifq, e_list) {
Packit Service dfccb1
		list_for_each_entry(top, &ifp->tracking_vrrp, e_list) {
Packit Service dfccb1
			vrrp = top->obj.vrrp;
Packit Service dfccb1
			if (top->weight == VRRP_NOT_TRACK_IF)
Packit c22fc9
				continue;
Packit c22fc9
Packit Service dfccb1
			if (!top->weight) {
Packit Service dfccb1
				if (IF_FLAGS_UP(ifp) != (top->weight_multiplier == 1)) {
Packit c22fc9
					/* The instance is down */
Packit Service dfccb1
					log_message(LOG_INFO, "(%s): entering FAULT state (interface %s down)", vrrp->iname, ifp->ifname);
Packit Service dfccb1
					vrrp->state = VRRP_STATE_FAULT;
Packit Service dfccb1
					vrrp->num_script_if_fault++;
Packit c22fc9
				}
Packit Service dfccb1
			} else if (IF_FLAGS_UP(ifp)) {
Packit Service dfccb1
				if (top->weight > 0)
Packit Service dfccb1
					vrrp->total_priority += top->weight * top->weight_multiplier;
Packit Service dfccb1
			} else {
Packit Service dfccb1
				if (top->weight < 0)
Packit Service dfccb1
					vrrp->total_priority += top->weight * top->weight_multiplier;
Packit c22fc9
			}
Packit c22fc9
		}
Packit c22fc9
	}
Packit c22fc9
}
Packit c22fc9
Packit c22fc9
static void
Packit Service dfccb1
initialise_vrrp_file_tracking_priorities(void)
Packit c22fc9
{
Packit Service dfccb1
	tracked_file_t *tfile;
Packit Service dfccb1
	tracking_obj_t *top;
Packit Service dfccb1
	vrrp_t *vrrp;
Packit c22fc9
	int status;
Packit c22fc9
Packit Service dfccb1
	list_for_each_entry(tfile, &vrrp_data->vrrp_track_files, e_list) {
Packit Service dfccb1
		list_for_each_entry(top, &tfile->tracking_obj, e_list) {
Packit Service dfccb1
			vrrp = top->obj.vrrp;
Packit Service dfccb1
			status = !top->weight ? (!!tfile->last_status == (top->weight_multiplier == 1) ? -254 : 0 ) : tfile->last_status * top->weight * top->weight_multiplier;
Packit c22fc9
Packit c22fc9
			if (status <= -254) {
Packit c22fc9
				/* The instance is down */
Packit Service dfccb1
				log_message(LOG_INFO, "(%s): entering FAULT state (tracked file %s has status %i)", vrrp->iname, tfile->fname, status);
Packit Service dfccb1
				vrrp->state = VRRP_STATE_FAULT;
Packit Service dfccb1
				vrrp->num_script_if_fault++;
Packit c22fc9
			}
Packit c22fc9
			else
Packit Service dfccb1
				vrrp->total_priority += (status > 253 ? 253 : status);
Packit c22fc9
		}
Packit c22fc9
	}
Packit c22fc9
}
Packit c22fc9
Packit Service dfccb1
#ifdef _WITH_CN_PROC_
Packit Service dfccb1
static void
Packit Service dfccb1
initialise_process_tracking_priorities(void)
Packit Service dfccb1
{
Packit Service dfccb1
	vrrp_tracked_process_t *tprocess;
Packit Service dfccb1
	tracking_obj_t *top;
Packit Service dfccb1
	vrrp_t *vrrp;
Packit Service dfccb1
Packit Service dfccb1
	list_for_each_entry(tprocess, &vrrp_data->vrrp_track_processes, e_list) {
Packit Service dfccb1
		tprocess->have_quorum =
Packit Service dfccb1
			(tprocess->num_cur_proc >= tprocess->quorum &&
Packit Service dfccb1
			 tprocess->num_cur_proc <= tprocess->quorum_max);
Packit Service dfccb1
Packit Service dfccb1
		list_for_each_entry(top, &tprocess->tracking_vrrp, e_list) {
Packit Service dfccb1
			vrrp = top->obj.vrrp;
Packit Service dfccb1
			if (!top->weight) {
Packit Service dfccb1
				if (tprocess->have_quorum != (top->weight_multiplier == 1)) {
Packit Service dfccb1
					/* The instance is down */
Packit Service dfccb1
					log_message(LOG_INFO, "(%s) entering FAULT state (tracked process %s"
Packit Service dfccb1
							      " quorum not achieved)"
Packit Service dfccb1
							    , vrrp->iname, tprocess->pname);
Packit Service dfccb1
					vrrp->state = VRRP_STATE_FAULT;
Packit Service dfccb1
					vrrp->num_script_if_fault++;
Packit Service dfccb1
				}
Packit Service dfccb1
			}
Packit Service dfccb1
			else if (tprocess->have_quorum) {
Packit Service dfccb1
				if (top->weight > 0)
Packit Service dfccb1
					vrrp->total_priority += top->weight * top->weight_multiplier;
Packit Service dfccb1
			}
Packit Service dfccb1
			else {
Packit Service dfccb1
				if (top->weight < 0)
Packit Service dfccb1
					vrrp->total_priority += top->weight * top->weight_multiplier;
Packit Service dfccb1
			}
Packit Service dfccb1
		}
Packit Service dfccb1
	}
Packit Service dfccb1
}
Packit Service dfccb1
#endif
Packit Service dfccb1
Packit c22fc9
static void
Packit c22fc9
initialise_vrrp_tracking_priorities(vrrp_t *vrrp)
Packit c22fc9
{
Packit c22fc9
	tracked_sc_t *tsc;
Packit c22fc9
#ifdef _WITH_BFD_
Packit c22fc9
	tracked_bfd_t *tbfd;
Packit c22fc9
#endif
Packit c22fc9
Packit c22fc9
	/* If no src address has been specified, and the interface doesn't have
Packit c22fc9
	 * an appropriate address, put the interface into fault state */
Packit c22fc9
	if (vrrp->saddr.ss_family == AF_UNSPEC) {
Packit Service dfccb1
		/* The instance is down */
Packit Service dfccb1
		log_message(LOG_INFO, "(%s) entering FAULT state (no IPv%d address for interface)"
Packit Service dfccb1
				    , vrrp->iname, vrrp->family == AF_INET ? 4 : 6);
Packit c22fc9
		vrrp->state = VRRP_STATE_FAULT;
Packit Service dfccb1
		vrrp->num_script_if_fault++;
Packit c22fc9
	}
Packit c22fc9
Packit c22fc9
	/* Initialise the vrrp instance's tracked scripts */
Packit Service dfccb1
	list_for_each_entry(tsc, &vrrp->track_script, e_list)
Packit c22fc9
		initialise_track_script_state(tsc, vrrp);
Packit c22fc9
Packit c22fc9
#ifdef _WITH_BFD_
Packit c22fc9
	/* Initialise the vrrp instance's tracked scripts */
Packit Service dfccb1
	list_for_each_entry(tbfd, &vrrp->track_bfd, e_list)
Packit c22fc9
		initialise_track_bfd_state(tbfd, vrrp);
Packit c22fc9
#endif
Packit c22fc9
Packit c22fc9
	/* If have a sync group, initialise it's tracked scripts and bfds */
Packit c22fc9
	if (vrrp->sync) {
Packit Service dfccb1
		list_for_each_entry(tsc, &vrrp->sync->track_script, e_list)
Packit c22fc9
			initialise_track_script_state(tsc, vrrp);
Packit c22fc9
	}
Packit c22fc9
Packit c22fc9
	vrrp_set_effective_priority(vrrp);
Packit c22fc9
}
Packit c22fc9
Packit c22fc9
void
Packit c22fc9
initialise_tracking_priorities(void)
Packit c22fc9
{
Packit c22fc9
	vrrp_t *vrrp;
Packit c22fc9
Packit c22fc9
	/* Check for instance down due to an interface */
Packit c22fc9
	initialise_interface_tracking_priorities();
Packit c22fc9
Packit Service dfccb1
	initialise_vrrp_file_tracking_priorities();
Packit Service dfccb1
Packit Service dfccb1
#ifdef _WITH_CN_PROC_
Packit Service dfccb1
	initialise_process_tracking_priorities();
Packit Service dfccb1
#endif
Packit c22fc9
Packit c22fc9
	/* Now check for tracking scripts, files, bfd etc. */
Packit Service dfccb1
	list_for_each_entry(vrrp, &vrrp_data->vrrp, e_list) {
Packit c22fc9
		/* Set effective priority and fault state */
Packit c22fc9
		initialise_vrrp_tracking_priorities(vrrp);
Packit c22fc9
Packit c22fc9
		if (vrrp->sync) {
Packit c22fc9
			if (vrrp->state == VRRP_STATE_FAULT) {
Packit c22fc9
				if (vrrp->sync->state != VRRP_STATE_FAULT) {
Packit c22fc9
					vrrp->sync->state = VRRP_STATE_FAULT;
Packit Service dfccb1
					log_message(LOG_INFO, "VRRP_Group(%s): Syncing %s to FAULT state"
Packit Service dfccb1
							    , vrrp->sync->gname, vrrp->iname);
Packit c22fc9
				}
Packit c22fc9
Packit c22fc9
				vrrp->sync->num_member_fault++;
Packit c22fc9
			}
Packit c22fc9
			if (vrrp->num_script_init) {
Packit c22fc9
				/* Update init count on sync group if needed */
Packit c22fc9
				vrrp->sync->num_member_init++;
Packit c22fc9
				if (vrrp->sync->state != VRRP_STATE_FAULT)
Packit c22fc9
					vrrp->sync->state = VRRP_STATE_INIT;
Packit c22fc9
			}
Packit c22fc9
		}
Packit c22fc9
	}
Packit c22fc9
}
Packit c22fc9
Packit Service dfccb1
#ifdef _WITH_CN_PROC_
Packit c22fc9
void
Packit Service dfccb1
process_update_track_process_status(vrrp_tracked_process_t *tprocess, bool now_up)
Packit c22fc9
{
Packit Service dfccb1
	tracking_obj_t *top;
Packit Service dfccb1
	vrrp_t *vrrp;
Packit c22fc9
Packit Service dfccb1
	log_message(LOG_INFO, "Quorum %s for tracked process %s", now_up ? "gained" : "lost", tprocess->pname);
Packit c22fc9
Packit Service dfccb1
	list_for_each_entry(top, &tprocess->tracking_vrrp, e_list) {
Packit Service dfccb1
		vrrp = top->obj.vrrp;
Packit Service dfccb1
		if (!top->weight) {
Packit Service dfccb1
			if (now_up == (top->weight_multiplier == 1))
Packit Service dfccb1
				try_up_instance(vrrp, false);
Packit Service dfccb1
			else
Packit Service dfccb1
				down_instance(vrrp);
Packit c22fc9
		}
Packit Service dfccb1
		else if (vrrp->base_priority != VRRP_PRIO_OWNER) {
Packit Service dfccb1
			if ((top->weight > 0) == now_up)
Packit Service dfccb1
				vrrp->total_priority += top->weight * top->weight_multiplier;
Packit Service dfccb1
			else
Packit Service dfccb1
				vrrp->total_priority -= top->weight * top->weight_multiplier;
Packit Service dfccb1
			vrrp_set_effective_priority(vrrp);
Packit c22fc9
		}
Packit c22fc9
	}
Packit c22fc9
}
Packit c22fc9
#endif