Esempio n. 1
0
void applet_run_active()
{
	struct appctx *curr;
	struct stream_interface *si;

	if (LIST_ISEMPTY(&applet_active_queue))
		return;

	/* move active queue to run queue */
	applet_active_queue.n->p = &applet_cur_queue;
	applet_active_queue.p->n = &applet_cur_queue;

	applet_cur_queue = applet_active_queue;
	LIST_INIT(&applet_active_queue);

	/* The list is only scanned from the head. This guarantees that if any
	 * applet removes another one, there is no side effect while walking
	 * through the list.
	 */
	while (!LIST_ISEMPTY(&applet_cur_queue)) {
		curr = LIST_ELEM(applet_cur_queue.n, typeof(curr), runq);
		si = curr->owner;

		/* Now we'll try to allocate the input buffer. We wake up the
		 * applet in all cases. So this is the applet responsibility to
		 * check if this buffer was allocated or not. This let a chance
		 * for applets to do some other processing if needed. */
		if (!channel_alloc_buffer(si_ic(si), &curr->buffer_wait))
			si_applet_cant_put(si);

		/* We always pretend the applet can't get and doesn't want to
		 * put, it's up to it to change this if needed. This ensures
		 * that one applet which ignores any event will not spin.
		 */
		si_applet_cant_get(si);
		si_applet_stop_put(si);

		curr->applet->fct(curr);
		si_applet_wake_cb(si);
		channel_release_buffer(si_ic(si), &curr->buffer_wait);

		if (applet_cur_queue.n == &curr->runq) {
			/* curr was left in the list, move it back to the active list */
			LIST_DEL(&curr->runq);
			LIST_ADDQ(&applet_active_queue, &curr->runq);
		}
	}
}
Esempio n. 2
0
/* Interface queue helpers*/
void
free_interface_queue(void)
{
	if (!LIST_ISEMPTY(if_queue))
		free_list(if_queue);
	if_queue = NULL;
}
Esempio n. 3
0
bool
find_rttables_table(const char *name, unsigned int *id)
{
	element e;
	char	*endptr;

	*id = strtoul(name, &endptr, 0);
	if (endptr != name && *endptr == '\0')
		return true;

	if (!rt_list && !read_rttables())
		return false;

	if (LIST_ISEMPTY(rt_list))
		return false;

	for (e = LIST_HEAD(rt_list); e; ELEMENT_NEXT(e)) {
		rt_entry_t *rte = ELEMENT_DATA(e);

		if (!strcmp(rte->name, name)) {
			*id = rte->id;
			return true;
		}
	}
	return false;
}
Esempio n. 4
0
/* VRRP handlers */
static void
vrrp_sync_group_handler(vector_t *strvec)
{
	list l;
	element e;
	vrrp_sgroup_t *sg;
	char* gname;

	if (vector_count(strvec) != 2) {
		log_message(LOG_INFO, "vrrp_sync_group must have a name - skipping");
		skip_block();
		return;
	}

	gname = vector_slot(strvec, 1);

	/* check group doesn't already exist */
	if (!LIST_ISEMPTY(vrrp_data->vrrp_sync_group)) {
		l = vrrp_data->vrrp_sync_group;
		for (e = LIST_HEAD(l); e; ELEMENT_NEXT(e)) {
			sg = ELEMENT_DATA(e);
			if (!strcmp(gname,sg->gname)) {
				log_message(LOG_INFO, "vrrp sync group %s already defined", gname);
				skip_block();
				return;
			}
		}
	}

	alloc_vrrp_sync_group(gname);
}
Esempio n. 5
0
/* Set a virtualserver IPVS rules */
static int
init_service_vs(virtual_server_t * vs)
{
	/* Init the VS root */
	if (!ISALIVE(vs) || vs->vsgname) {
		if (!ipvs_cmd(LVS_CMD_ADD, check_data->vs_group, vs, NULL))
			return 0;
		else
			SET_ALIVE(vs);
	}

	/* Processing real server queue */
	if (!LIST_ISEMPTY(vs->rs)) {
		if (vs->alpha && ! vs->reloaded)
			vs->quorum_state = DOWN;
		if (!init_service_rs(vs))
			return 0;
	}

	/* if the service was reloaded, we may have got/lost quorum due to quorum setting changed */
	if (vs->reloaded)
		update_quorum_state(vs);

	return 1;
}
Esempio n. 6
0
void
netlink_rulelist(list rule_list, int cmd, bool force)
{
	ip_rule_t *iprule;
	element e;

	/* No rules to add */
	if (LIST_ISEMPTY(rule_list))
		return;

	/* If force is set, we try to remove all the rules, but the
	 * rule might not exist. That's not an error, so indicate not
	 * to report such a situation */
	if (force && cmd == IPRULE_DEL)
	         netlink_error_ignore = ENOENT;

	for (e = LIST_HEAD(rule_list); e; ELEMENT_NEXT(e)) {
		iprule = ELEMENT_DATA(e);
		if (force ||
		    (cmd && !iprule->set) ||
		    (!cmd && iprule->set)) {
			if (netlink_rule(iprule, cmd) > 0)
				iprule->set = (cmd) ? 1 : 0;
			else
				iprule->set = 0;
		}
	}

	netlink_error_ignore = 0;
}
Esempio n. 7
0
static void
vrrp_handler(vector_t *strvec)
{
	list l;
	element e;
	vrrp_t *vrrp;
	char *iname;

	if (vector_count(strvec) != 2) {
		log_message(LOG_INFO, "vrrp_instance must have a name");
		skip_block();
		return;
	}

	iname = vector_slot(strvec,1);

	/* Make sure the vrrp instance doesn't already exist */
	if (!LIST_ISEMPTY(vrrp_data->vrrp)) {
		l = vrrp_data->vrrp;
		for (e = LIST_HEAD(l); e; ELEMENT_NEXT(e)) {
			vrrp = ELEMENT_DATA(e);
			if (!strcmp(iname,vrrp->iname)) {
				log_message(LOG_INFO, "vrrp instance %s already defined", iname );
				skip_block();
				return;
			}
		}
	}

	alloc_vrrp(iname);
}
Esempio n. 8
0
/* Sync checkers activity with netlink kernel reflection */
void
update_checker_activity(uint32_t address, int enable)
{
	checker *checker_obj;
	element e;

	/* Display netlink operation */
	if (debug & 32)
		log_message(LOG_INFO, "Netlink reflector reports IP %s %s",
		       inet_ntop2(address), (enable) ? "added" : "removed");

	/* Processing Healthcheckers queue */
	if (!LIST_ISEMPTY(checkers_queue))
		for (e = LIST_HEAD(checkers_queue); e; ELEMENT_NEXT(e)) {
			checker_obj = ELEMENT_DATA(e);
			if (CHECKER_VIP(checker_obj) == address && CHECKER_HA_SUSPEND(checker_obj)) {
				if (!CHECKER_ENABLED(checker_obj) && enable)
					log_message(LOG_INFO,
					       "Activating healtchecker for service [%s:%d]",
					       inet_ntop2(CHECKER_RIP(checker_obj)),
					       ntohs(CHECKER_RPORT(checker_obj)));
				if (CHECKER_ENABLED(checker_obj) && !enable)
					log_message(LOG_INFO,
					       "Suspending healtchecker for service [%s:%d]",
					       inet_ntop2(CHECKER_RIP(checker_obj)),
					       ntohs(CHECKER_RPORT(checker_obj)));
				checker_obj->enabled = enable;
			}
		}
}
Esempio n. 9
0
/* Add/Delete a list of IP addresses */
void
netlink_iplist(list ip_list, int cmd)
{
	ip_address_t *ipaddr;
	element e;

	/* No addresses in this list */
	if (LIST_ISEMPTY(ip_list))
		return;

	/*
	 * If "--dont-release-vrrp" is set then try to release addresses
	 * that may be there, even if we didn't set them.
	 */
	for (e = LIST_HEAD(ip_list); e; ELEMENT_NEXT(e)) {
		ipaddr = ELEMENT_DATA(e);
		if ((cmd == IPADDRESS_ADD && !ipaddr->set) ||
		    (cmd == IPADDRESS_DEL &&
		     (ipaddr->set || __test_bit(DONT_RELEASE_VRRP_BIT, &debug)))) {
			if (netlink_ipaddress(ipaddr, cmd) > 0)
				ipaddr->set = !(cmd == IPADDRESS_DEL);
			else
				ipaddr->set = false;
		}
	}
}
Esempio n. 10
0
static bool
find_entry(const char *name, unsigned int *id, list *l, const char* file_name, const struct rt_entry* default_list, uint32_t max)
{
	element e;
	char	*endptr;
	unsigned long l_id;

	l_id = strtoul(name, &endptr, 0);
	*id = (unsigned int)l_id;
	if (endptr != name && *endptr == '\0')
		return (*id <= max);

	if (!(*l))
		initialise_list(l, file_name, default_list, max);

	if (LIST_ISEMPTY(*l))
		return false;

	for (e = LIST_HEAD(*l); e; ELEMENT_NEXT(e)) {
		rt_entry_t *rte = ELEMENT_DATA(e);

		if (!strcmp(rte->name, name)) {
			*id = rte->id;
			return true;
		}
	}
	return false;
}
Esempio n. 11
0
/* Set a realserver IPVS rules */
static int
init_service_rs(virtual_server_t * vs)
{
	element e;
	real_server_t *rs;

	if (LIST_ISEMPTY(vs->rs)) {
		log_message(LOG_WARNING, "VS [%s] has no configured RS! Skipping RS activation."
				       , FMT_VS(vs));
		return 1;
	}

	for (e = LIST_HEAD(vs->rs); e; ELEMENT_NEXT(e)) {
		rs = ELEMENT_DATA(e);

		if (rs->reloaded) {
			if (rs->iweight != rs->pweight)
				update_svr_wgt(rs->iweight, vs, rs, 0);
			/* Do not re-add failed RS instantly on reload */
			continue;
		}
		/* In alpha mode, be pessimistic (or realistic?) and don't
		 * add real servers into the VS pool. They will get there
		 * later upon healthchecks recovery (if ever).
		 */
		if (!vs->alpha && !ISALIVE(rs)) {
			ipvs_cmd(LVS_CMD_ADD_DEST, vs, rs);
			SET_ALIVE(rs);
		}
	}

	return 1;
}
Esempio n. 12
0
vrrp_rt *
vrrp_index_lookup(const int vrid, const int fd)
{
	vrrp_rt *vrrp;
	element e;
	list l = &vrrp_data->vrrp_index[vrid];

	/* return if list is empty */
	if (LIST_ISEMPTY(l))
		return NULL;

	/*
	 * If list size's is 1 then no collisions. So
	 * Test and return the singleton.
	 */
	if (LIST_SIZE(l) == 1) {
		vrrp = ELEMENT_DATA(LIST_HEAD(l));
		return (vrrp->fd_in == fd) ? vrrp : NULL;
	}

	/*
	 * List collision on the vrid bucket. The same
	 * vrid is used on a different interface. We perform
	 * a fd lookup as collisions solver.
	 */ 
	for (e = LIST_HEAD(l); e; ELEMENT_NEXT(e)) {
		vrrp =  ELEMENT_DATA(e);
		if (vrrp->fd_in == fd)
			return vrrp;
	}

	/* No match */
	return NULL;
}
Esempio n. 13
0
/* Log interface message */
static void vrrp_log_int_down(vrrp_t *vrrp)
{
	if (!IF_ISUP(vrrp->ifp))
		log_message(LOG_INFO, "Kernel is reporting: interface %s DOWN",
		       IF_NAME(vrrp->ifp));
	if (!LIST_ISEMPTY(vrrp->track_ifp))
		vrrp_log_tracked_down(vrrp->track_ifp);
}
Esempio n. 14
0
/* Interface queue helpers*/
void
free_interface_queue(void)
{
	if (!LIST_ISEMPTY(if_queue))
		free_list(if_queue);
	if_queue = NULL;
	kernel_netlink_close();
}
Esempio n. 15
0
static void vrrp_log_int_up(vrrp_t *vrrp)
{
	if (IF_ISUP(vrrp->ifp))
		log_message(LOG_INFO, "Kernel is reporting: interface %s UP",
		       IF_NAME(vrrp->ifp));
	if (!LIST_ISEMPTY(vrrp->track_ifp))
		log_message(LOG_INFO, "Kernel is reporting: tracked interface are UP");
}
Esempio n. 16
0
/* dump the checkers_queue */
void
dump_checkers_queue(void)
{
	if (!LIST_ISEMPTY(checkers_queue)) {
		log_message(LOG_INFO, "------< Health checkers >------");
		dump_list(checkers_queue);
	}
}
Esempio n. 17
0
/* This function returns the type of the data returned by the sample_expr.
 * It assumes that the <expr> and all of its converters are properly
 * initialized.
 */
inline
int smp_expr_output_type(struct sample_expr *expr)
{
	struct sample_conv_expr *smp_expr;

	if (!LIST_ISEMPTY(&expr->conv_exprs)) {
		smp_expr = LIST_PREV(&expr->conv_exprs, struct sample_conv_expr *, list);
		return smp_expr->conv->out_type;
	}
Esempio n. 18
0
void
vrrp_print_data(void)
{
	FILE *file;
	file = fopen ("/tmp/keepalived.data","w");

	fprintf(file, "------< VRRP Topology >------\n");
	vrrp_print_list(file, vrrp_data->vrrp, &vrrp_print);

	if (!LIST_ISEMPTY(vrrp_data->vrrp_sync_group)) {
		fprintf(file, "------< VRRP Sync groups >------\n");
		vrrp_print_list(file, vrrp_data->vrrp_sync_group, &vgroup_print);
	}
        fclose(file);
}
Esempio n. 19
0
/*
 * Reflect base interface flags on VMAC interfaces.
 * VMAC interfaces should never update it own flags, only be reflected
 * by the base interface flags.
 */
void
if_vmac_reflect_flags(const int ifindex, const unsigned long flags)
{
	interface_t *ifp;
	element e;

	if (LIST_ISEMPTY(if_queue) || !ifindex)
		return;

	for (e = LIST_HEAD(if_queue); e; ELEMENT_NEXT(e)) {
		ifp = ELEMENT_DATA(e);
		if (ifp->vmac && ifp->base_ifindex == ifindex)
			ifp->flags = flags;
	}
}
Esempio n. 20
0
/* Return interface from interface index */
interface_t *
if_get_by_ifindex(const int ifindex)
{
	interface_t *ifp;
	element e;

	if (LIST_ISEMPTY(if_queue))
		return NULL;

	for (e = LIST_HEAD(if_queue); e; ELEMENT_NEXT(e)) {
		ifp = ELEMENT_DATA(e);
		if (ifp->ifindex == ifindex)
			return ifp;
	}
	return NULL;
}
Esempio n. 21
0
vrrp_script *
find_script_by_name(char *name)
{
	element e;
	vrrp_script *scr;

	if (LIST_ISEMPTY(vrrp_data->vrrp_script))
		return NULL;

	for (e = LIST_HEAD(vrrp_data->vrrp_script); e; ELEMENT_NEXT(e)) {
		scr = ELEMENT_DATA(e);
		if (!strcmp(scr->sname, name))
			return scr;
	}
	return NULL;
}
Esempio n. 22
0
interface_t *
if_get_by_ifname(const char *ifname)
{
	interface_t *ifp;
	element e;

	if (LIST_ISEMPTY(if_queue))
		return NULL;

	for (e = LIST_HEAD(if_queue); e; ELEMENT_NEXT(e)) {
		ifp = ELEMENT_DATA(e);
		if (!strcmp(ifp->ifname, ifname))
			return ifp;
	}
	return NULL;
}
Esempio n. 23
0
/* Returns the sum of all RS weight in a virtual server. */
static long
weigh_live_realservers(virtual_server_t * vs)
{
	element e;
	real_server_t *svr;
	long count = 0;

	if (LIST_ISEMPTY(vs->rs))
		return count;

	for (e = LIST_HEAD(vs->rs); e; ELEMENT_NEXT(e)) {
		svr = ELEMENT_DATA(e);
		if (ISALIVE(svr))
			count += svr->weight;
	}
	return count;
}
Esempio n. 24
0
/* Sync checkers activity with netlink kernel reflection */
void
update_checker_activity(sa_family_t family, void *address, int enable)
{
	checker_t *checker;
	sa_family_t vip_family;
	element e;
	char addr_str[INET6_ADDRSTRLEN];
	void *addr;

	/* Display netlink operation */
	if (debug & 32) {
		inet_ntop(family, address, addr_str, sizeof(addr_str));
		log_message(LOG_INFO, "Netlink reflector reports IP %s %s"
				    , addr_str, (enable) ? "added" : "removed");
	}

	/* Processing Healthcheckers queue */
	if (!LIST_ISEMPTY(checkers_queue)) {
		for (e = LIST_HEAD(checkers_queue); e; ELEMENT_NEXT(e)) {
			checker = ELEMENT_DATA(e);
			vip_family = checker->vs->addr.ss_family;

			if (vip_family != family)
				continue;

			if (family == AF_INET6) {
				addr = (void *) &((struct sockaddr_in6 *)&checker->vs->addr)->sin6_addr;
			} else {
				addr = (void *) &((struct sockaddr_in *)&checker->vs->addr)->sin_addr;
			}

			if (inaddr_equal(family, addr, address) &&
			    CHECKER_HA_SUSPEND(checker)) {
				if (!CHECKER_ENABLED(checker) && enable)
					log_message(LOG_INFO, "Activating healthchecker for service [%s]:%d"
							    , inet_sockaddrtos(&checker->rs->addr)
							    , ntohs(inet_sockaddrport(&checker->rs->addr)));
				if (CHECKER_ENABLED(checker) && !enable)
					log_message(LOG_INFO, "Suspending healthchecker for service [%s]:%d"
							    , inet_sockaddrtos(&checker->rs->addr)
							    , ntohs(inet_sockaddrport(&checker->rs->addr)));
				checker->enabled = enable;
			}
		}
	}
}
Esempio n. 25
0
/* add/remove iptable drop rules to iplist */
void
handle_iptable_rule_to_iplist(struct ipt_handle *h, list ip_list, int cmd, char *ifname, bool force)
{
	ip_address_t *ipaddr;
	element e;

	/* No addresses in this list */
	if (LIST_ISEMPTY(ip_list))
		return;

	for (e = LIST_HEAD(ip_list); e; ELEMENT_NEXT(e)) {
		ipaddr = ELEMENT_DATA(e);
		if ((cmd == IPADDRESS_DEL) == ipaddr->iptable_rule_set ||
		    force)
			handle_iptable_rule_to_vip(ipaddr, cmd, ifname, h);
	}
}
Esempio n. 26
0
/* Main entry point */
void
smtp_alert(real_server_t * rs, vrrp_t * vrrp,
	   vrrp_sgroup_t * vgroup, const char *subject, const char *body)
{
	smtp_t *smtp;

	/* Only send mail if email specified */
	if (!LIST_ISEMPTY(global_data->email) && global_data->smtp_server.ss_family != 0) {
		/* allocate & initialize smtp argument data structure */
		smtp = (smtp_t *) MALLOC(sizeof(smtp_t));
		smtp->subject = (char *) MALLOC(MAX_HEADERS_LENGTH);
		smtp->body = (char *) MALLOC(MAX_BODY_LENGTH);
		smtp->buffer = (char *) MALLOC(SMTP_BUFFER_MAX);
		smtp->email_to = (char *) MALLOC(SMTP_BUFFER_MAX);

		/* format subject if rserver is specified */
		if (rs) {
			snprintf(smtp->subject, MAX_HEADERS_LENGTH, "[%s] Realserver [%s]:%d - %s"
					      , global_data->router_id
					      , inet_sockaddrtos(&rs->addr)
					      , ntohs(inet_sockaddrport(&rs->addr))
					      , subject);
		} else if (vrrp)
			snprintf(smtp->subject, MAX_HEADERS_LENGTH, "[%s] VRRP Instance %s - %s"
					      , global_data->router_id
					      , vrrp->iname
					      , subject);
		else if (vgroup)
			snprintf(smtp->subject, MAX_HEADERS_LENGTH, "[%s] VRRP Group %s - %s"
					      , global_data->router_id
					      , vgroup->gname
					      , subject);
		else if (global_data->router_id)
			snprintf(smtp->subject, MAX_HEADERS_LENGTH, "[%s] %s"
					      , global_data->router_id
					      , subject);
		else
			snprintf(smtp->subject, MAX_HEADERS_LENGTH, "%s", subject);

		strncpy(smtp->body, body, MAX_BODY_LENGTH);
		build_to_header_rcpt_addrs(smtp);

		smtp_connect(smtp);
	}
}
Esempio n. 27
0
/* Remove a virtualserver IPVS rule */
static int
clear_service_vs(virtual_server_t * vs)
{
	/* Processing real server queue */
	if (!LIST_ISEMPTY(vs->rs)) {
		if (vs->s_svr) {
			if (ISALIVE(vs->s_svr))
				ipvs_cmd(LVS_CMD_DEL_DEST, vs, vs->s_svr);
		} else if (!clear_service_rs(vs, vs->rs))
			return 0;
		/* The above will handle Omega case for VS as well. */
	}

	ipvs_cmd(LVS_CMD_DEL, vs, NULL);

	UNSET_ALIVE(vs);
	return 1;
}
Esempio n. 28
0
/* Set instances group pointer */
void
vrrp_sync_set_group(vrrp_sgroup *vgroup)
{
	vrrp_rt *vrrp;
	char *str;
	int i;

	for (i = 0; i < VECTOR_SIZE(vgroup->iname); i++) {
		str = VECTOR_SLOT(vgroup->iname, i);
		vrrp = vrrp_get_instance(str);
		if (vrrp) {
			if (LIST_ISEMPTY(vgroup->index_list))
				vgroup->index_list = alloc_list(NULL, NULL);
			list_add(vgroup->index_list, vrrp);
			vrrp->sync = vgroup;
		}
	}
}
Esempio n. 29
0
/* Set instances group pointer */
void
vrrp_sync_set_group(vrrp_sgroup_t *vgroup)
{
	vrrp_t *vrrp;
	char *str;
	int i;

	for (i = 0; i < vector_size(vgroup->iname); i++) {
		str = vector_slot(vgroup->iname, i);
		vrrp = vrrp_get_instance(str);
		if (vrrp) {
			if (LIST_ISEMPTY(vgroup->index_list))
				vgroup->index_list = alloc_list(NULL, NULL);
			list_add(vgroup->index_list, vrrp);
			vrrp->sync = vgroup;
		}
	}
}
Esempio n. 30
0
/* Set a virtualserver IPVS rules */
static int
init_service_vs(virtual_server * vs)
{
	/* Init the VS root */
	if (!ISALIVE(vs) || vs->vsgname) {
		if (!ipvs_cmd(LVS_CMD_ADD, check_data->vs_group, vs, NULL))
			return 0;
		else
			SET_ALIVE(vs);
	}

	/* Processing real server queue */
	if (!LIST_ISEMPTY(vs->rs)) {
		if (vs->alpha)
			vs->quorum_state = DOWN;
		if (!init_service_rs(vs))
			return 0;
	}
	return 1;
}