コード例 #1
0
ファイル: ipwrapper.c プロジェクト: coraltech/keepalived
/* Store new weight in real_server struct and then update kernel. */
void
update_svr_wgt(int weight, virtual_server * vs, real_server * rs)
{
	char rsip[INET6_ADDRSTRLEN];

	if (weight != rs->weight) {
		log_message(LOG_INFO, "Changing weight from %d to %d for %s service [%s]:%d of VS [%s]:%d"
				    , rs->weight
				    , weight
				    , ISALIVE(rs) ? "active" : "inactive"
				    , inet_sockaddrtos2(&rs->addr, rsip)
				    , ntohs(inet_sockaddrport(&rs->addr))
				    , (vs->vsgname) ? vs->vsgname : inet_sockaddrtos(&vs->addr)
				    , ntohs(inet_sockaddrport(&vs->addr)));
		rs->weight = weight;
		/*
		 * Have weight change take effect now only if rs is in
		 * the pool and alive and the quorum is met (or if
		 * there is no sorry server). If not, it will take
		 * effect later when it becomes alive.
		 */
		if (rs->set && ISALIVE(rs) &&
		    (vs->quorum_state == UP || !vs->s_svr || !ISALIVE(vs->s_svr)))
			ipvs_cmd(LVS_CMD_EDIT_DEST, check_data->vs_group, vs, rs);
		update_quorum_state(vs);
	}
}
コード例 #2
0
ファイル: ipvswrapper.c プロジェクト: Addision/LVS
/* Fill IPVS rule with root vs infos */
void
ipvs_set_rule(int cmd, virtual_server * vs, real_server * rs)
{
	/* Clean up target rule */
	memset(urule, 0, sizeof (struct ip_vs_rule_user));

	strncpy(urule->sched_name, vs->sched, IP_VS_SCHEDNAME_MAXLEN);
	urule->weight = 1;
	urule->conn_flags = vs->loadbalancing_kind;
	urule->netmask = ((u_int32_t) 0xffffffff);
	urule->protocol = vs->service_type;

	if (!parse_timeout(vs->timeout_persistence, &urule->timeout))
		log_message(LOG_INFO, "IPVS : Virtual service [%s]:%d illegal timeout."
				    , inet_ntop2(inet_sockaddrip4(&vs->addr))
				    , ntohs(inet_sockaddrport(&vs->addr)));

	if (urule->timeout != 0 || vs->granularity_persistence)
		urule->vs_flags = IP_VS_SVC_F_PERSISTENT;

	if (cmd == IP_VS_SO_SET_ADD || cmd == IP_VS_SO_SET_DEL)
		if (vs->granularity_persistence)
			urule->netmask = vs->granularity_persistence;

	/* SVR specific */
	if (rs) {
		if (cmd == IP_VS_SO_SET_ADDDEST
		    || cmd == IP_VS_SO_SET_DELDEST
		    || cmd == IP_VS_SO_SET_EDITDEST) {
			urule->weight = rs->weight;
			urule->daddr = inet_sockaddrip4(&rs->addr);
			urule->dport = inet_sockaddrport(&rs->addr);
		}
	}
}
コード例 #3
0
ファイル: check_tcp.c プロジェクト: tclh123/lvs-tool
int
tcp_check_thread(thread_t * thread)
{
	checker_t *checker;
	tcp_checker_t *tcp_check;
	int status;

	checker = THREAD_ARG(thread);
	tcp_check = CHECKER_ARG(checker);

	status = tcp_socket_state(thread->u.fd, thread, tcp_check_thread);

	/* If status = connect_success, TCP connection to remote host is established.
	 * Otherwise we have a real connection error or connection timeout.
	 */
	if (status == connect_success) {
		close(thread->u.fd);

		if (!svr_checker_up(UP, checker->id, checker->rs)) {
			log_message(LOG_INFO, "TCP connection to [%s]:%d success."
					    , inet_sockaddrtos(&tcp_check->dst)
					    , ntohs(inet_sockaddrport(&tcp_check->dst)));
			smtp_alert(checker->rs, NULL, NULL,
				   "UP",
				   "=> TCP CHECK succeed on service <=");
			update_svr_checker_state(UP, checker->id
						   , checker->vs
						   , checker->rs);
		}

	} else {

		if (svr_checker_up(DOWN, checker->id, checker->rs)) {
			log_message(LOG_INFO, "TCP connection to [%s]:%d failed !!!"
					    , inet_sockaddrtos(&tcp_check->dst)
					    , ntohs(inet_sockaddrport(&tcp_check->dst)));
			smtp_alert(checker->rs, NULL, NULL,
				   "DOWN",
				   "=> TCP CHECK failed on service <=");
			update_svr_checker_state(DOWN, checker->id
						     , checker->vs
						     , checker->rs);
		}

	}

	/* Register next timer checker */
	if (status != connect_in_progress)
		thread_add_timer(thread->master, tcp_connect_thread, checker,
				 checker->vs->delay_loop);
	return 0;
}
コード例 #4
0
ファイル: ipvswrapper.c プロジェクト: Addision/LVS
static int
ipvs_laddr_cmd(int cmd, list vs_group, virtual_server * vs)
{
	local_addr_group *laddr_group = ipvs_get_laddr_group_by_name(vs->local_addr_gname, 
							check_data->laddr_group);
	if (!laddr_group) {
		log_message(LOG_ERR, "No address in group %s", vs->local_addr_gname);
		return IPVS_ERROR;
	}

	memset(srule, 0, sizeof(ipvs_service_t));
	srule->netmask = (vs->addr.ss_family == AF_INET6) ? 128 : ((u_int32_t) 0xffffffff);
	srule->protocol = vs->service_type;

	if(vs->vsgname) {
		ipvs_laddr_vsg_cmd(cmd, vs_group, vs, laddr_group);
	} else {
		if (!vs->vfwmark) {
			srule->af = vs->addr.ss_family;
			if (vs->addr.ss_family == AF_INET6)
				inet_sockaddrip6(&vs->addr, &srule->addr.in6);
			else
				srule->addr.ip = inet_sockaddrip4(&vs->addr);
			srule->port = inet_sockaddrport(&vs->addr);

			ipvs_laddr_group_cmd(cmd, laddr_group);
		}
	}

	return IPVS_SUCCESS;
}
コード例 #5
0
ファイル: ipvswrapper.c プロジェクト: Addision/LVS
/* IPVS group range rule */
static void
ipvs_group_range_cmd(int cmd, virtual_server_group_entry *vsg_entry)
{
	uint32_t addr_ip, ip;

	if (vsg_entry->addr.ss_family == AF_INET6) {
		inet_sockaddrip6(&vsg_entry->addr, &srule->addr.in6);
		ip = srule->addr.in6.s6_addr32[3];
	} else {
		ip = inet_sockaddrip4(&vsg_entry->addr);
	}

	/* Set Address Family */
	srule->af = vsg_entry->addr.ss_family;

	/* Parse the whole range */
	for (addr_ip = ip;
	     ((addr_ip >> 24) & 0xFF) <= vsg_entry->range;
	     addr_ip += 0x01000000) {
		if (srule->af == AF_INET6) {
			if (srule->netmask == 0xffffffff)
				srule->netmask = 128;
			srule->addr.in6.s6_addr32[3] = addr_ip;
		} else {
			srule->addr.ip = addr_ip;
		}
		srule->port = inet_sockaddrport(&vsg_entry->addr);

		/* Talk to the IPVS channel */
		ipvs_talk(cmd);
	}
}
コード例 #6
0
ファイル: ipvswrapper.c プロジェクト: Addision/LVS
int
ipvs_laddr_remove_entry(virtual_server *vs, local_addr_entry *laddr_entry)
{
	memset(srule, 0, sizeof(ipvs_service_t));
	srule->protocol = vs->service_type;

	if (vs->vsgname) {
		ipvs_rm_lentry_from_vsg(laddr_entry, vs->vsgname);
	} else if (!vs->vfwmark) {
		srule->af = vs->addr.ss_family;
		if (vs->addr.ss_family == AF_INET6) {
			srule->netmask = 128;
			inet_sockaddrip6(&vs->addr, &srule->addr.in6);
		} else {
			srule->netmask = 0xffffffff;
			srule->addr.ip = inet_sockaddrip4(&vs->addr);
		}
		srule->port = inet_sockaddrport(&vs->addr);

		if (laddr_entry->range) {
			ipvs_laddr_range_cmd(IP_VS_SO_SET_DELLADDR, laddr_entry);
		} else {
			memset(laddr_rule, 0, sizeof(ipvs_laddr_t));
			laddr_rule->af = laddr_entry->addr.ss_family;
			if (laddr_entry->addr.ss_family == AF_INET6)
				inet_sockaddrip6(&laddr_entry->addr, &laddr_rule->addr.in6);
			else
				laddr_rule->addr.ip = inet_sockaddrip4(&laddr_entry->addr);

			ipvs_talk(IP_VS_SO_SET_DELLADDR);
		}
	}

	return IPVS_SUCCESS;
}
コード例 #7
0
ファイル: ipvswrapper.c プロジェクト: Addision/LVS
/* Remove a specific vs group entry */
int
ipvs_group_remove_entry(virtual_server *vs, virtual_server_group_entry *vsge)
{
	real_server *rs;
	int err = 0;
	element e;
	list l = vs->rs;

	/* Clean target rules */
	memset(urule, 0, sizeof (struct ip_vs_rule_user));

	/* Process realserver queue */
	for (e = LIST_HEAD(l); e; ELEMENT_NEXT(e)) {
		rs = ELEMENT_DATA(e);

		if (rs->alive) {
			/* Prepare the IPVS rule */
			if (urule->daddr) {
				/* Setting IPVS rule with vs root rs */
				ipvs_set_rule(IP_VS_SO_SET_DELDEST, vs, rs);
			} else {
				urule->weight = rs->weight;
				urule->daddr = inet_sockaddrip4(&rs->addr);
				urule->dport = inet_sockaddrport(&rs->addr);
			}

			/* Set vs rule */
			if (vsge->range) {
				ipvs_group_range_cmd(IP_VS_SO_SET_DELDEST, vsge);
			} else {
				urule->vfwmark = vsge->vfwmark;
				urule->vaddr = inet_sockaddrip4(&vsge->addr);
				urule->vport = inet_sockaddrport(&vsge->addr);

				/* Talk to the IPVS channel */
				err = ipvs_talk(IP_VS_SO_SET_DELDEST);
			}
		}
	}

	/* Remove VS entry */
	if (vsge->range)
		err = ipvs_group_range_cmd(IP_VS_SO_SET_DEL, vsge);
	else
		err = ipvs_talk(IP_VS_SO_SET_DEL);
	return err;
}
コード例 #8
0
ファイル: ipvswrapper.c プロジェクト: Addision/LVS
/* Fill IPVS rule with root vs infos */
void
ipvs_set_rule(int cmd, virtual_server * vs, real_server * rs)
{
	/* Clean target rule */
	memset(drule, 0, sizeof(ipvs_dest_t));

	drule->weight = 1;
	drule->u_threshold = 0;
	drule->l_threshold = 0;
	drule->conn_flags = vs->loadbalancing_kind;
	strncpy(srule->sched_name, vs->sched, IP_VS_SCHEDNAME_MAXLEN);
	srule->netmask = (vs->addr.ss_family == AF_INET6) ? 128 : ((u_int32_t) 0xffffffff);
	srule->protocol = vs->service_type;

	if (!parse_timeout(vs->timeout_persistence, &srule->timeout))
		log_message(LOG_INFO, "IPVS : Virtual service [%s]:%d illegal timeout."
				    , inet_ntop2(inet_sockaddrip4(&vs->addr))
				    , ntohs(inet_sockaddrport(&vs->addr)));

	srule->est_timeout = atoi(vs->est_timeout);

	if (srule->timeout != 0 || vs->granularity_persistence)
		srule->flags = IP_VS_SVC_F_PERSISTENT;

	if (cmd == IP_VS_SO_SET_ADD || cmd == IP_VS_SO_SET_DEL)
		if (vs->granularity_persistence)
			srule->netmask = vs->granularity_persistence;

	if(vs->syn_proxy)
		srule->flags |= IP_VS_SVC_F_SYNPROXY;

	/* SVR specific */
	if (rs) {
		if (cmd == IP_VS_SO_SET_ADDDEST || cmd == IP_VS_SO_SET_DELDEST ||
		    cmd == IP_VS_SO_SET_EDITDEST) {
			drule->af = rs->addr.ss_family;
			if (rs->addr.ss_family == AF_INET6)
				inet_sockaddrip6(&rs->addr, &drule->addr.in6);
			else
				drule->addr.ip = inet_sockaddrip4(&rs->addr);
			drule->port = inet_sockaddrport(&rs->addr);
			drule->weight = rs->weight;	
			drule->u_threshold = rs->u_threshold;
			drule->l_threshold = rs->l_threshold;
		}
	}
}
コード例 #9
0
ファイル: ipwrapper.c プロジェクト: coraltech/keepalived
/* Remove a realserver IPVS rule */
static int
clear_service_rs(list vs_group, virtual_server * vs, list l)
{
	element e;
	real_server *rs;
	char rsip[INET6_ADDRSTRLEN];

	for (e = LIST_HEAD(l); e; ELEMENT_NEXT(e)) {
		rs = ELEMENT_DATA(e);
		if (ISALIVE(rs)) {
			if (!ipvs_cmd(LVS_CMD_DEL_DEST, vs_group, vs, rs))
				return 0;
			UNSET_ALIVE(rs);
			if (!vs->omega)
				continue;

			/* In Omega mode we call VS and RS down notifiers
			 * all the way down the exit, as necessary.
			 */
			if (rs->notify_down) {
				log_message(LOG_INFO, "Executing [%s] for service [%s]:%d in VS [%s]:%d"
						    , rs->notify_down
						    , inet_sockaddrtos2(&rs->addr, rsip)
						    , ntohs(inet_sockaddrport(&rs->addr))
						    , (vs->vsgname) ? vs->vsgname : inet_sockaddrtos(&vs->addr)
						    , ntohs(inet_sockaddrport(&vs->addr)));
				notify_exec(rs->notify_down);
			}

			/* Sooner or later VS will lose the quorum (if any). However,
			 * we don't push in a sorry server then, hence the regression
			 * is intended.
			 */
			if (vs->quorum_state == UP && vs->quorum_down &&
			    weigh_live_realservers(vs) < vs->quorum - vs->hysteresis) {
				vs->quorum_state = DOWN;
				log_message(LOG_INFO, "Executing [%s] for VS [%s]:%d"
						    , vs->quorum_down
						    , (vs->vsgname) ? vs->vsgname : inet_sockaddrtos(&vs->addr)
						    , ntohs(inet_sockaddrport(&vs->addr)));
				notify_exec(vs->quorum_down);
			}
		}
	}

	return 1;
}
コード例 #10
0
ファイル: check_api.c プロジェクト: jfharden/keepalived
/* 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;
			}
		}
	}
}
コード例 #11
0
ファイル: check_smtp.c プロジェクト: Addision/LVS
/*
 * Used as a callback from dump_list() to print out all
 * the list elements in smtp_checker->host.
 */
void
smtp_dump_host(void *data)
{
        smtp_host_t *smtp_host = data;
        log_message(LOG_INFO, "   Checked ip = %s", inet_sockaddrtos(&smtp_host->dst));
        log_message(LOG_INFO, "           port = %d", ntohs(ntohs(inet_sockaddrport(&smtp_host->dst))));
	if (smtp_host->bindto.ss_family)
        	log_message(LOG_INFO, "           bindto = %s", inet_sockaddrtos(&smtp_host->bindto));
}
コード例 #12
0
ファイル: check_api.c プロジェクト: jfharden/keepalived
/* dump checker data */
static void
dump_checker(void *data)
{
	checker_t *checker = data;
	log_message(LOG_INFO, " [%s]:%d"
			    , inet_sockaddrtos(&checker->rs->addr)
			    , ntohs(inet_sockaddrport(&checker->rs->addr)));
	(*checker->dump_func) (checker);
}
コード例 #13
0
ファイル: ipvswrapper.c プロジェクト: Addision/LVS
/* set IPVS group rules */
static int
ipvs_group_cmd(int cmd, list vs_group, real_server * rs, char * vsgname)
{
	virtual_server_group *vsg = ipvs_get_group_by_name(vsgname, vs_group);
	virtual_server_group_entry *vsg_entry;
	list l;
	element e;
	int err = 1;

	/* return if jointure fails */
	if (!vsg) return -1;

	/* visit addr_ip list */
	l = vsg->addr_ip;
	for (e = LIST_HEAD(l); e; ELEMENT_NEXT(e)) {
		vsg_entry = ELEMENT_DATA(e);
		urule->vaddr = inet_sockaddrip4(&vsg_entry->addr);
		urule->vport = inet_sockaddrport(&vsg_entry->addr);

		/* Talk to the IPVS channel */
		if (IPVS_ALIVE(cmd, vsg_entry, rs)) {
			err = ipvs_talk(cmd);
			IPVS_SET_ALIVE(cmd, vsg_entry);
		}
	}

	/* visit vfwmark list */
	l = vsg->vfwmark;
	urule->vaddr = 0;
	urule->vport = 0;
	for (e = LIST_HEAD(l); e; ELEMENT_NEXT(e)) {
		vsg_entry = ELEMENT_DATA(e);
		urule->vfwmark = vsg_entry->vfwmark;

		/* Talk to the IPVS channel */
		if (IPVS_ALIVE(cmd, vsg_entry, rs)) {
			err = ipvs_talk(cmd);
			IPVS_SET_ALIVE(cmd, vsg_entry);
		}
	}

	/* visit range list */
	l = vsg->range;
	urule->vfwmark = 0;
	for (e = LIST_HEAD(l); e; ELEMENT_NEXT(e)) {
		vsg_entry = ELEMENT_DATA(e);

		/* Talk to the IPVS channel */
		if (IPVS_ALIVE(cmd, vsg_entry, rs)) {
			err = ipvs_group_range_cmd(cmd, vsg_entry);
			IPVS_SET_ALIVE(cmd, vsg_entry);
		}
	}

	return err;
}
コード例 #14
0
ファイル: check_tcp.c プロジェクト: tclh123/lvs-tool
void
dump_tcp_check(void *data)
{
	tcp_checker_t *tcp_chk = CHECKER_DATA(data);

	log_message(LOG_INFO, "   Keepalive method = TCP_CHECK");
	log_message(LOG_INFO, "   Connection port = %d", ntohs(inet_sockaddrport(&tcp_chk->dst)));
	if (tcp_chk->bindto.ss_family)
		log_message(LOG_INFO, "   Bind to = %s", inet_sockaddrtos(&tcp_chk->bindto));
	log_message(LOG_INFO, "   Connection timeout = %d", tcp_chk->connection_to/TIMER_HZ);
}
コード例 #15
0
ファイル: ipvswrapper.c プロジェクト: Addision/LVS
/* Set/Remove a RS or a local address group from a VS */
int
ipvs_cmd(int cmd, list vs_group, virtual_server * vs, real_server * rs)
{
	/* Set/Remove local address */
	if (cmd == IP_VS_SO_SET_ADDLADDR || cmd == IP_VS_SO_SET_DELLADDR)	
		return ipvs_laddr_cmd(cmd, vs_group, vs);

	/* Allocate the room */
	memset(srule, 0, sizeof(ipvs_service_t));
	ipvs_set_rule(cmd, vs, rs);

	/* Does the service use inhibit flag ? */
	if (cmd == IP_VS_SO_SET_DELDEST && rs->inhibit) {
		drule->weight = 0;
		cmd = IP_VS_SO_SET_EDITDEST;
	}
	if (cmd == IP_VS_SO_SET_ADDDEST && rs->inhibit && rs->set)
		cmd = IP_VS_SO_SET_EDITDEST;

	/* Set flag */
	if (cmd == IP_VS_SO_SET_ADDDEST && !rs->set)
		rs->set = 1;
	if (cmd == IP_VS_SO_SET_DELDEST && rs->set)
		rs->set = 0;

	/* Set vs rule and send to kernel */
	if (vs->vsgname) {
		ipvs_group_cmd(cmd, vs_group, rs, vs->vsgname);
	} else {
		if (vs->vfwmark) {
			srule->af = AF_INET;
			srule->fwmark = vs->vfwmark;
		} else {
			srule->af = vs->addr.ss_family;
			if (vs->addr.ss_family == AF_INET6)
				inet_sockaddrip6(&vs->addr, &srule->addr.in6);
			else
				srule->addr.ip = inet_sockaddrip4(&vs->addr);
			srule->port = inet_sockaddrport(&vs->addr);
		}

		/* Talk to the IPVS channel */
		ipvs_talk(cmd);
	}

	return IPVS_SUCCESS;
}
コード例 #16
0
ファイル: check_api.c プロジェクト: jfharden/keepalived
/* register checkers to the global I/O scheduler */
void
register_checkers_thread(void)
{
	checker_t *checker;
	element e;

	for (e = LIST_HEAD(checkers_queue); e; ELEMENT_NEXT(e)) {
		checker = ELEMENT_DATA(e);
		log_message(LOG_INFO, "Activating healthchecker for service [%s]:%d"
				    , inet_sockaddrtos(&checker->rs->addr)
				    , ntohs(inet_sockaddrport(&checker->rs->addr)));
		CHECKER_ENABLE(checker);
		if (checker->launch)
			thread_add_timer(master, checker->launch, checker,
					 BOOTSTRAP_DELAY);
	}
}
コード例 #17
0
ファイル: smtp.c プロジェクト: Grip/keepalived-1
/* 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);
	}
}
コード例 #18
0
ファイル: ipvswrapper.c プロジェクト: Addision/LVS
/* IPVS group range rule */
static int
ipvs_group_range_cmd(int cmd, virtual_server_group_entry *vsg_entry)
{
	uint32_t addr_ip;
	int err = 0;

	/* Parse the whole range */
	for (addr_ip = inet_sockaddrip4(&vsg_entry->addr);
	     ((addr_ip >> 24) & 0xFF) <= vsg_entry->range;
	     addr_ip += 0x01000000) {
		urule->vaddr = addr_ip;
		urule->vport = inet_sockaddrport(&vsg_entry->addr);

		/* Talk to the IPVS channel */
		err = ipvs_talk(cmd);
	}

	return err;
}
コード例 #19
0
ファイル: ipvswrapper.c プロジェクト: Addision/LVS
/* Set/Remove a RS from a VS */
int
ipvs_cmd(int cmd, list vs_group, virtual_server * vs, real_server * rs)
{
	int err = 0;

	/* Prepare target rule */
	ipvs_set_rule(cmd, vs, rs);

	/* Does the service use inhibit flag ? */
	if (cmd == IP_VS_SO_SET_DELDEST && rs->inhibit) {
		urule->weight = 0;
		cmd = IP_VS_SO_SET_EDITDEST;
	}
	if (cmd == IP_VS_SO_SET_ADDDEST && rs->inhibit && rs->set)
		cmd = IP_VS_SO_SET_EDITDEST;

	/* Set flag */
	if (cmd == IP_VS_SO_SET_ADDDEST && !rs->set)
		rs->set = 1;
	if (cmd == IP_VS_SO_SET_DELDEST && rs->set)
		rs->set = 0;

	/* Set vs rule and send to kernel */
	if (vs->vsgname) {
		err = ipvs_group_cmd(cmd, vs_group, rs, vs->vsgname);
	} else {
		if (vs->vfwmark) {
			urule->vfwmark = vs->vfwmark;
		} else {
			urule->vaddr = inet_sockaddrip4(&vs->addr);
			urule->vport = inet_sockaddrport(&vs->addr);
		}

		/* Talk to the IPVS channel */
		err = ipvs_talk(cmd);
	}

	return err;
}
コード例 #20
0
ファイル: ipwrapper.c プロジェクト: coraltech/keepalived
/* add or remove _alive_ real servers from a virtual server */
void
perform_quorum_state(virtual_server *vs, int add)
{
	element e;
	real_server *rs;

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

	log_message(LOG_INFO, "%s the pool for VS [%s]:%d"
			    , add?"Adding alive servers to":"Removing alive servers from"
			    , (vs->vsgname) ? vs->vsgname : inet_sockaddrtos(&vs->addr)
			    , ntohs(inet_sockaddrport(&vs->addr)));
	for (e = LIST_HEAD(vs->rs); e; ELEMENT_NEXT(e)) {
		rs = ELEMENT_DATA(e);
		if (!ISALIVE(rs)) /* We only handle alive servers */
			continue;
		if (add)
			rs->alive = 0;
		ipvs_cmd(add?LVS_CMD_ADD_DEST:LVS_CMD_DEL_DEST, check_data->vs_group, vs, rs);
		rs->alive = 1;
	}
}
コード例 #21
0
ファイル: ipwrapper.c プロジェクト: coraltech/keepalived
/* set quorum state depending on current weight of real servers */
void
update_quorum_state(virtual_server * vs)
{
	char rsip[INET6_ADDRSTRLEN];

	/* If we have just gained quorum, it's time to consider notify_up. */
	if (vs->quorum_state == DOWN &&
	    weigh_live_realservers(vs) >= vs->quorum + vs->hysteresis) {
		vs->quorum_state = UP;
		log_message(LOG_INFO, "Gained quorum %lu+%lu=%lu <= %u for VS [%s]:%d"
				    , vs->quorum
				    , vs->hysteresis
				    , vs->quorum + vs->hysteresis
				    , weigh_live_realservers(vs)
				    , (vs->vsgname) ? vs->vsgname : inet_sockaddrtos(&vs->addr)
				    , ntohs(inet_sockaddrport(&vs->addr)));
		if (vs->s_svr && ISALIVE(vs->s_svr)) {
			log_message(LOG_INFO, "Removing sorry server [%s]:%d from VS [%s]:%d"
					    , inet_sockaddrtos2(&vs->s_svr->addr, rsip)
					    , ntohs(inet_sockaddrport(&vs->s_svr->addr))
					    , (vs->vsgname) ? vs->vsgname : inet_sockaddrtos(&vs->addr)
					    , ntohs(inet_sockaddrport(&vs->addr)));

			ipvs_cmd(LVS_CMD_DEL_DEST, check_data->vs_group, vs, vs->s_svr);
			vs->s_svr->alive = 0;

			/* Adding back alive real servers */
			perform_quorum_state(vs, 1);
		}
		if (vs->quorum_up) {
			log_message(LOG_INFO, "Executing [%s] for VS [%s]:%d"
					    , vs->quorum_up
					    , (vs->vsgname) ? vs->vsgname : inet_sockaddrtos(&vs->addr)
					    , ntohs(inet_sockaddrport(&vs->addr)));
			notify_exec(vs->quorum_up);
		}
		return;
	}

	/* If we have just lost quorum for the VS, we need to consider
	 * VS notify_down and sorry_server cases
	 */
	if (vs->quorum_state == UP &&
	    weigh_live_realservers(vs) < vs->quorum - vs->hysteresis) {
		vs->quorum_state = DOWN;
		log_message(LOG_INFO, "Lost quorum %lu-%lu=%lu > %u for VS [%s]:%d"
				    , vs->quorum
				    , vs->hysteresis
				    , vs->quorum - vs->hysteresis
				    , weigh_live_realservers(vs)
				    , (vs->vsgname) ? vs->vsgname : inet_sockaddrtos(&vs->addr)
				    , ntohs(inet_sockaddrport(&vs->addr)));
		if (vs->quorum_down) {
			log_message(LOG_INFO, "Executing [%s] for VS [%s]:%d"
					    , vs->quorum_down
					    , (vs->vsgname) ? vs->vsgname : inet_sockaddrtos(&vs->addr)
					    , ntohs(inet_sockaddrport(&vs->addr)));
			notify_exec(vs->quorum_down);
		}
		if (vs->s_svr) {
			log_message(LOG_INFO, "Adding sorry server [%s]:%d to VS [%s]:%d"
					    , inet_sockaddrtos2(&vs->s_svr->addr, rsip)
					    , ntohs(inet_sockaddrport(&vs->s_svr->addr))
					    , (vs->vsgname) ? vs->vsgname : inet_sockaddrtos(&vs->addr)
					    , ntohs(inet_sockaddrport(&vs->addr)));

			/* the sorry server is now up in the pool, we flag it alive */
			ipvs_cmd(LVS_CMD_ADD_DEST, check_data->vs_group, vs, vs->s_svr);
			vs->s_svr->alive = 1;

			/* Remove remaining alive real servers */
			perform_quorum_state(vs, 0);
		}
		return;
	}
}
コード例 #22
0
ファイル: ipvswrapper.c プロジェクト: Addision/LVS
static void
ipvs_rm_lentry_from_vsg(local_addr_entry *laddr_entry, char *vsgname)
{
	list l;
	element e;
	virtual_server_group *vsg;
	virtual_server_group_entry *vsg_entry;

	/* it's not old_check_data. help to ISALIVE check later  */
	vsg = ipvs_get_group_by_name(vsgname, check_data->vs_group);
	if (!vsg) return;

	l = vsg->addr_ip;
	for (e = LIST_HEAD(l); e; ELEMENT_NEXT(e)) {
		vsg_entry = ELEMENT_DATA(e);
		if (!ISALIVE(vsg_entry))
			continue;

		srule->af = vsg_entry->addr.ss_family;
		if (vsg_entry->addr.ss_family == AF_INET6) {
			srule->netmask = 128;
			inet_sockaddrip6(&vsg_entry->addr, &srule->addr.in6);
		} else {
			srule->netmask = 0xffffffff;
			srule->addr.ip = inet_sockaddrip4(&vsg_entry->addr);
		}
		srule->port = inet_sockaddrport(&vsg_entry->addr);

		if (laddr_entry->range)
			ipvs_laddr_range_cmd(IP_VS_SO_SET_DELLADDR, laddr_entry);
		else {
			memset(laddr_rule, 0, sizeof(ipvs_laddr_t));
			laddr_rule->af = laddr_entry->addr.ss_family;
			if (laddr_entry->addr.ss_family == AF_INET6)
				inet_sockaddrip6(&laddr_entry->addr, &laddr_rule->addr.in6);
			else
				laddr_rule->addr.ip = inet_sockaddrip4(&laddr_entry->addr);

				ipvs_talk(IP_VS_SO_SET_DELLADDR);
		}
	}

	l = vsg->range;
	for (e = LIST_HEAD(l); e; ELEMENT_NEXT(e)) {
		vsg_entry = ELEMENT_DATA(e);
		uint32_t addr_ip, ip;
		if (!ISALIVE(vsg_entry))
			continue;

		srule->af = vsg_entry->addr.ss_family;
		srule->netmask = (vsg_entry->addr.ss_family == AF_INET6) ? 128 : ((u_int32_t) 0xffffffff);
		srule->port = inet_sockaddrport(&vsg_entry->addr);
		if (vsg_entry->addr.ss_family == AF_INET6) {
			inet_sockaddrip6(&vsg_entry->addr, &srule->addr.in6);
			ip = srule->addr.in6.s6_addr32[3];
		} else {
			ip = inet_sockaddrip4(&vsg_entry->addr);
		}

		for (addr_ip = ip;
		     ((addr_ip >> 24) & 0xFF) <= vsg_entry->range;
		     addr_ip += 0x01000000) {
			if (srule->af == AF_INET6)
				srule->addr.in6.s6_addr32[3] = addr_ip;
			else
				srule->addr.ip = addr_ip;

			if (laddr_entry->range)
				ipvs_laddr_range_cmd(IP_VS_SO_SET_DELLADDR, laddr_entry);
			else {
				memset(laddr_rule, 0, sizeof(ipvs_laddr_t));
				laddr_rule->af = laddr_entry->addr.ss_family;
				if (laddr_entry->addr.ss_family == AF_INET6)
					inet_sockaddrip6(&laddr_entry->addr, &laddr_rule->addr.in6);
				else
					laddr_rule->addr.ip = inet_sockaddrip4(&laddr_entry->addr);

				ipvs_talk(IP_VS_SO_SET_DELLADDR);
			}
		}
	}
}
コード例 #23
0
ファイル: ipvswrapper.c プロジェクト: Addision/LVS
void
ipvs_new_laddr_add(virtual_server *vs, local_addr_group *laddr_group)
{
	local_addr_entry *laddr_entry;
	list l;
	element e;

	/* the unalive vs will be set later*/
	if (!vs->vsgname && !ISALIVE(vs))
		return;

	memset(srule, 0, sizeof(ipvs_service_t));
	srule->netmask = (vs->addr.ss_family == AF_INET6) ? 128 : ((u_int32_t) 0xffffffff);
	srule->protocol = vs->service_type;

	l = laddr_group->addr_ip;
	for (e = LIST_HEAD(l); e; ELEMENT_NEXT(e)) {
		laddr_entry = ELEMENT_DATA(e);
		if (ISALIVE(laddr_entry))
			continue;

		memset(laddr_rule, 0, sizeof(ipvs_laddr_t));
		laddr_rule->af = laddr_entry->addr.ss_family;
		if (laddr_entry->addr.ss_family == AF_INET6)
			inet_sockaddrip6(&laddr_entry->addr, &laddr_rule->addr.in6);
		else
			laddr_rule->addr.ip = inet_sockaddrip4(&laddr_entry->addr);

		if (vs->vsgname) {
			ipvs_new_laddr_vsg(vs);
		} else {
			srule->af = vs->addr.ss_family;
			if (srule->af == AF_INET6)
				inet_sockaddrip6(&vs->addr, &srule->addr.in6);
			else
				srule->addr.ip = inet_sockaddrip4(&vs->addr);
			srule->port = inet_sockaddrport(&vs->addr);

			/* local address group channel */
			ipvs_talk(IP_VS_SO_SET_ADDLADDR);
		}
	}

	l = laddr_group->range;
	for (e = LIST_HEAD(l); e; ELEMENT_NEXT(e)) {
		laddr_entry = ELEMENT_DATA(e);
		uint32_t addr_ip, ip;

		if (ISALIVE(laddr_entry))
			 continue;

		memset(laddr_rule, 0, sizeof(ipvs_laddr_t));
		laddr_rule->af = laddr_entry->addr.ss_family;

		if (laddr_entry->addr.ss_family == AF_INET6) {
			inet_sockaddrip6(&laddr_entry->addr, &laddr_rule->addr.in6);
			ip = laddr_rule->addr.in6.s6_addr32[3];
		} else {
			ip = inet_sockaddrip4(&laddr_entry->addr);
		}

		for (addr_ip = ip; ((addr_ip >> 24) & 0xFF) <= laddr_entry->range;
						     addr_ip += 0x01000000) {
			if (laddr_entry->addr.ss_family == AF_INET6)
				laddr_rule->addr.in6.s6_addr32[3] = addr_ip;
			else
				laddr_rule->addr.ip = addr_ip;

			if (vs->vsgname) {
				ipvs_new_laddr_vsg(vs);
			} else {
				srule->af = vs->addr.ss_family;
				if (srule->af == AF_INET6)
					inet_sockaddrip6(&vs->addr, &srule->addr.in6);
				else
					srule->addr.ip = inet_sockaddrip4(&vs->addr);
				srule->port = inet_sockaddrport(&vs->addr);

				/* local address group channel */
				ipvs_talk(IP_VS_SO_SET_ADDLADDR);
			}
		}
	}
}
コード例 #24
0
ファイル: ipvswrapper.c プロジェクト: Addision/LVS
static void
ipvs_new_laddr_vsg(virtual_server *vs)
{
	list l;
	element e;
	virtual_server_group *vsg;
	virtual_server_group_entry *vsg_entry;

	vsg = ipvs_get_group_by_name(vs->vsgname, check_data->vs_group);
	if (!vsg) return;

	/* visit addr_ip list */
	l = vsg->addr_ip;
	for (e = LIST_HEAD(l); e; ELEMENT_NEXT(e)) {
		vsg_entry = ELEMENT_DATA(e);

		/* will be set later */
		if (!ISALIVE(vsg_entry))
			continue;

		srule->af = vsg_entry->addr.ss_family;
		if (srule->af == AF_INET6) {
			if (srule->netmask == 0xffffffff)
				srule->netmask = 128;
			inet_sockaddrip6(&vsg_entry->addr, &srule->addr.in6);
		} else
			srule->addr.ip = inet_sockaddrip4(&vsg_entry->addr);
		srule->port = inet_sockaddrport(&vsg_entry->addr);

		/* local address group channel */
		ipvs_talk(IP_VS_SO_SET_ADDLADDR);
	}

	/* visit range list */
	l = vsg->range;
	for (e = LIST_HEAD(l); e; ELEMENT_NEXT(e)) {
		vsg_entry = ELEMENT_DATA(e);
		uint32_t addr_ip, ip;

		/* will be set later */
		if (!ISALIVE(vsg_entry))
			continue;

		srule->af = vsg_entry->addr.ss_family;
		if (srule->af == AF_INET6) {
			inet_sockaddrip6(&vsg_entry->addr, &srule->addr.in6);
			ip = srule->addr.in6.s6_addr32[3];
		} else {
			ip = inet_sockaddrip4(&vsg_entry->addr);
		}

		/* Parse the whole range */
		for (addr_ip = ip;
		     ((addr_ip >> 24) & 0xFF) <= vsg_entry->range;
		     addr_ip += 0x01000000) {
			if (srule->af == AF_INET6) {
				if (srule->netmask == 0xffffffff)
					srule->netmask = 128;
				srule->addr.in6.s6_addr32[3] = addr_ip;
			} else {
				srule->addr.ip = addr_ip;
			}
			srule->port = inet_sockaddrport(&vsg_entry->addr);

			ipvs_talk(IP_VS_SO_SET_ADDLADDR);
		}
	}
}
コード例 #25
0
ファイル: ipwrapper.c プロジェクト: coraltech/keepalived
/* manipulate add/remove rs according to alive state */
void
perform_svr_state(int alive, virtual_server * vs, real_server * rs)
{
	char rsip[INET6_ADDRSTRLEN];

	/*
	 * | ISALIVE(rs) | alive | context
	 * | 0           | 0     | first check failed under alpha mode, unreachable here
	 * | 0           | 1     | RS went up, add it to the pool
	 * | 1           | 0     | RS went down, remove it from the pool
	 * | 1           | 1     | first check succeeded w/o alpha mode, unreachable here
	 */
	if (!ISALIVE(rs) && alive) {
		log_message(LOG_INFO, "%s service [%s]:%d to VS [%s]:%d"
				    , (rs->inhibit) ? "Enabling" : "Adding"
				    , inet_sockaddrtos2(&rs->addr, rsip)
				    , ntohs(inet_sockaddrport(&rs->addr))
				    , (vs->vsgname) ? vs->vsgname : inet_sockaddrtos(&vs->addr)
				    , ntohs(inet_sockaddrport(&vs->addr)));
		/* Add only if we have quorum or no sorry server */
		if (vs->quorum_state == UP || !vs->s_svr || !ISALIVE(vs->s_svr)) {
			ipvs_cmd(LVS_CMD_ADD_DEST, check_data->vs_group, vs, rs);
		}
		rs->alive = alive;
		if (rs->notify_up) {
			log_message(LOG_INFO, "Executing [%s] for service [%s]:%d in VS [%s]:%d"
					    , rs->notify_up
					    , inet_sockaddrtos2(&rs->addr, rsip)
					    , ntohs(inet_sockaddrport(&rs->addr))
					    , (vs->vsgname) ? vs->vsgname : inet_sockaddrtos(&vs->addr)
					    , ntohs(inet_sockaddrport(&vs->addr)));
			notify_exec(rs->notify_up);
		}

		/* We may have gained quorum */
		update_quorum_state(vs);
	}

	if (ISALIVE(rs) && !alive) {
		log_message(LOG_INFO, "%s service [%s]:%d from VS [%s]:%d"
				    , (rs->inhibit) ? "Disabling" : "Removing"
				    , inet_sockaddrtos2(&rs->addr, rsip)
				    , ntohs(inet_sockaddrport(&rs->addr))
				    , (vs->vsgname) ? vs->vsgname : inet_sockaddrtos(&vs->addr)
				    , ntohs(inet_sockaddrport(&vs->addr)));

		/* server is down, it is removed from the LVS realserver pool
		 * Remove only if we have quorum or no sorry server
		 */
		if (vs->quorum_state == UP || !vs->s_svr || !ISALIVE(vs->s_svr)) {
			ipvs_cmd(LVS_CMD_DEL_DEST, check_data->vs_group, vs, rs);
		}
		rs->alive = alive;
		if (rs->notify_down) {
			log_message(LOG_INFO, "Executing [%s] for service [%s]:%d in VS [%s]:%d"
					    , rs->notify_down
					    , inet_sockaddrtos2(&rs->addr, rsip)
					    , ntohs(inet_sockaddrport(&rs->addr))
					    , (vs->vsgname) ? vs->vsgname : inet_sockaddrtos(&vs->addr)
					    , ntohs(inet_sockaddrport(&vs->addr)));
			notify_exec(rs->notify_down);
		}

		/* We may have lost quorum */
		update_quorum_state(vs);
	}
}
コード例 #26
0
ファイル: check_snmp.c プロジェクト: TargetHolding/keepalived
static u_char*
check_snmp_virtualserver(struct variable *vp, oid *name, size_t *length,
			 int exact, size_t *var_len, WriteMethod **write_method)
{
	static struct counter64 counter64_ret;
	virtual_server_t *v;
	element e;

	if ((v = (virtual_server_t *)
	     snmp_header_list_table(vp, name, length, exact,
				    var_len, write_method,
				    check_data->vs)) == NULL)
		return NULL;

	switch (vp->magic) {
	case CHECK_SNMP_VSTYPE:
		if (v->vsgname)
			long_ret.u = 3;
		else if (v->vfwmark)
			long_ret.u = 1;
		else
			long_ret.u = 2;
		return (u_char*)&long_ret;
	case CHECK_SNMP_VSNAMEGROUP:
		if (!v->vsgname) break;
		*var_len = strlen(v->vsgname);
		return (u_char*)v->vsgname;
	case CHECK_SNMP_VSFWMARK:
		if (!v->vfwmark) break;
		long_ret.u = v->vfwmark;
		return (u_char*)&long_ret;
	case CHECK_SNMP_VSADDRTYPE:
		if (v->vfwmark || v->vsgname) break;
		long_ret.u = (v->addr.ss_family == AF_INET6) ? 2:1;
		return (u_char*)&long_ret;
	case CHECK_SNMP_VSADDRESS:
		if (v->vfwmark || v->vsgname) break;
		RETURN_IP46ADDRESS(v);
		break;
	case CHECK_SNMP_VSPORT:
		if (v->vfwmark || v->vsgname) break;
		long_ret.u = htons(inet_sockaddrport(&v->addr));
		return (u_char *)&long_ret;
	case CHECK_SNMP_VSPROTOCOL:
		long_ret.u = (v->service_type == IPPROTO_TCP)?1:2;
		return (u_char*)&long_ret;
	case CHECK_SNMP_VSLOADBALANCINGALGO:
		if (!strcmp(v->sched, "rr"))
			long_ret.u = 1;
		else if (!strcmp(v->sched, "wrr"))
			long_ret.u = 2;
		else if (!strcmp(v->sched, "lc"))
			long_ret.u = 3;
		else if (!strcmp(v->sched, "wlc"))
			long_ret.u = 4;
		else if (!strcmp(v->sched, "lblc"))
			long_ret.u = 5;
		else if (!strcmp(v->sched, "lblcr"))
			long_ret.u = 6;
		else if (!strcmp(v->sched, "dh"))
			long_ret.u = 7;
		else if (!strcmp(v->sched, "sh"))
			long_ret.u = 8;
		else if (!strcmp(v->sched, "sed"))
			long_ret.u = 9;
		else if (!strcmp(v->sched, "nq"))
			long_ret.u = 10;
		else
			long_ret.u = 99;
		return (u_char*)&long_ret;
	case CHECK_SNMP_VSLOADBALANCINGKIND:
		long_ret.u = 0;
		switch (v->loadbalancing_kind) {
		case IP_VS_CONN_F_MASQ:
			long_ret.u = 1;
			break;
		case IP_VS_CONN_F_DROUTE:
			long_ret.u = 2;
			break;
		case IP_VS_CONN_F_TUNNEL:
			long_ret.u = 3;
			break;
		}
		if (!long_ret.u) break;
		return (u_char*)&long_ret;
	case CHECK_SNMP_VSSTATUS:
		long_ret.u = v->alive?1:2;
		return (u_char*)&long_ret;
	case CHECK_SNMP_VSVIRTUALHOST:
		if (!v->virtualhost) break;
		*var_len = strlen(v->virtualhost);
		return (u_char*)v->virtualhost;
	case CHECK_SNMP_VSPERSIST:
		long_ret.u = (v->persistence_timeout)?1:2;
		return (u_char*)&long_ret;
	case CHECK_SNMP_VSPERSISTTIMEOUT:
		if (!v->persistence_timeout) break;
		long_ret.u = v->persistence_timeout;
		return (u_char*)&long_ret;
	case CHECK_SNMP_VSPERSISTGRANULARITY:
		if (!v->persistence_granularity || v->addr.ss_family == AF_INET6) break;
		*var_len = sizeof(v->persistence_granularity);
		return (u_char*)&v->persistence_granularity;
	case CHECK_SNMP_VSPERSISTGRANULARITY6:
		if (!v->persistence_granularity || v->addr.ss_family == AF_INET) break;
		*var_len = sizeof(v->persistence_granularity);
		return (u_char*)&v->persistence_granularity;
	case CHECK_SNMP_VSDELAYLOOP:
		if (v->delay_loop >= TIMER_MAX_SEC)
			long_ret.u = v->delay_loop/TIMER_HZ;
		else
			long_ret.u = v->delay_loop;
		return (u_char*)&long_ret;
	case CHECK_SNMP_VSHASUSPEND:
		long_ret.u = v->ha_suspend?1:2;
		return (u_char*)&long_ret;
#ifdef IP_VS_SVC_F_ONEPACKET
	case CHECK_SNMP_VSOPS:
		long_ret.u = v->flags & IP_VS_SVC_F_ONEPACKET?1:2;
		return (u_char*)&long_ret;
#endif
	case CHECK_SNMP_VSALPHA:
		long_ret.u = v->alpha?1:2;
		return (u_char*)&long_ret;
	case CHECK_SNMP_VSOMEGA:
		long_ret.u = v->omega?1:2;
		return (u_char*)&long_ret;
	case CHECK_SNMP_VSQUORUM:
		long_ret.u = v->quorum;
		return (u_char*)&long_ret;
	case CHECK_SNMP_VSQUORUMSTATUS:
		long_ret.u = v->quorum_state?1:2;
		return (u_char*)&long_ret;
	case CHECK_SNMP_VSQUORUMUP:
		if (!v->quorum_up) break;
		*var_len = strlen(v->quorum_up->name);
		return (u_char*)v->quorum_up->name;
	case CHECK_SNMP_VSQUORUMDOWN:
		if (!v->quorum_down) break;
		*var_len = strlen(v->quorum_down->name);
		return (u_char*)v->quorum_down->name;
	case CHECK_SNMP_VSHYSTERESIS:
		long_ret.u = v->hysteresis;
		return (u_char*)&long_ret;
	case CHECK_SNMP_VSREALTOTAL:
		if (LIST_ISEMPTY(v->rs))
			long_ret.u = 0;
		else
			long_ret.u = LIST_SIZE(v->rs);
		return (u_char*)&long_ret;
	case CHECK_SNMP_VSREALUP:
		long_ret.u = 0;
		if (!LIST_ISEMPTY(v->rs))
			for (e = LIST_HEAD(v->rs); e; ELEMENT_NEXT(e))
				if (((real_server_t *)ELEMENT_DATA(e))->alive)
					long_ret.u++;
		return (u_char*)&long_ret;
	case CHECK_SNMP_VSSTATSCONNS:
		ipvs_update_stats(v);
		long_ret.u = v->stats.conns;
		return (u_char*)&long_ret;
	case CHECK_SNMP_VSSTATSINPKTS:
		ipvs_update_stats(v);
		long_ret.u = v->stats.inpkts;
		return (u_char*)&long_ret;
	case CHECK_SNMP_VSSTATSOUTPKTS:
		ipvs_update_stats(v);
		long_ret.u = v->stats.outpkts;
		return (u_char*)&long_ret;
	case CHECK_SNMP_VSSTATSINBYTES:
		ipvs_update_stats(v);
		counter64_ret.low = v->stats.inbytes & 0xffffffff;
		counter64_ret.high = v->stats.inbytes >> 32;
		*var_len = sizeof(struct counter64);
		return (u_char*)&counter64_ret;
	case CHECK_SNMP_VSSTATSOUTBYTES:
		ipvs_update_stats(v);
		counter64_ret.low = v->stats.outbytes & 0xffffffff;
		counter64_ret.high = v->stats.outbytes >> 32;
		*var_len = sizeof(struct counter64);
		return (u_char*)&counter64_ret;
	case CHECK_SNMP_VSRATECPS:
		ipvs_update_stats(v);
		long_ret.u = v->stats.cps;
		return (u_char*)&long_ret;
	case CHECK_SNMP_VSRATEINPPS:
		ipvs_update_stats(v);
		long_ret.u = v->stats.inpps;
		return (u_char*)&long_ret;
	case CHECK_SNMP_VSRATEOUTPPS:
		ipvs_update_stats(v);
		long_ret.u = v->stats.outpps;
		return (u_char*)&long_ret;
	case CHECK_SNMP_VSRATEINBPS:
		ipvs_update_stats(v);
		long_ret.u = v->stats.inbps;
		return (u_char*)&long_ret;
	case CHECK_SNMP_VSRATEOUTBPS:
		ipvs_update_stats(v);
		long_ret.u = v->stats.outbps;
		return (u_char*)&long_ret;
#ifdef _WITH_LVS_64BIT_STATS_
	case CHECK_SNMP_VSSTATSCONNS64:
		ipvs_update_stats(v);
		counter64_ret.low = v->stats.conns & 0xffffffff;
		counter64_ret.high = v->stats.conns >> 32;
		*var_len = sizeof(struct counter64);
		return (u_char*)&counter64_ret;
	case CHECK_SNMP_VSSTATSINPKTS64:
		ipvs_update_stats(v);
		counter64_ret.low = v->stats.inpkts & 0xffffffff;
		counter64_ret.high = v->stats.inpkts >> 32;
		*var_len = sizeof(struct counter64);
		return (u_char*)&counter64_ret;
	case CHECK_SNMP_VSSTATSOUTPKTS64:
		ipvs_update_stats(v);
		counter64_ret.low = v->stats.outpkts & 0xffffffff;
		counter64_ret.high = v->stats.outpkts >> 32;
		*var_len = sizeof(struct counter64);
		return (u_char*)&counter64_ret;
	case CHECK_SNMP_VSRATECPSLOW:
		ipvs_update_stats(v);
		long_ret.u = v->stats.cps & 0xffffffff;
		return (u_char*)&counter64_ret;
	case CHECK_SNMP_VSRATECPSHIGH:
		ipvs_update_stats(v);
		long_ret.u = v->stats.cps >> 32;
		return (u_char*)&long_ret;
	case CHECK_SNMP_VSRATEINPPSLOW:
		ipvs_update_stats(v);
		long_ret.u = v->stats.inpps & 0xffffffff;
		return (u_char*)&counter64_ret;
	case CHECK_SNMP_VSRATEINPPSHIGH:
		ipvs_update_stats(v);
		long_ret.u = v->stats.inpps >> 32;
		return (u_char*)&long_ret;
	case CHECK_SNMP_VSRATEOUTPPSLOW:
		ipvs_update_stats(v);
		long_ret.u = v->stats.outpps & 0xffffffff;
		return (u_char*)&counter64_ret;
	case CHECK_SNMP_VSRATEOUTPPSHIGH:
		ipvs_update_stats(v);
		long_ret.u = v->stats.outpps >> 32;
		return (u_char*)&long_ret;
	case CHECK_SNMP_VSRATEINBPSLOW:
		ipvs_update_stats(v);
		long_ret.u = v->stats.inbps & 0xffffffff;
		return (u_char*)&counter64_ret;
	case CHECK_SNMP_VSRATEINBPSHIGH:
		ipvs_update_stats(v);
		long_ret.u = v->stats.inbps >> 32;
		return (u_char*)&long_ret;
	case CHECK_SNMP_VSRATEOUTBPSLOW:
		ipvs_update_stats(v);
		long_ret.u = v->stats.outbps & 0xffffffff;
		return (u_char*)&counter64_ret;
	case CHECK_SNMP_VSRATEOUTBPSHIGH:
		ipvs_update_stats(v);
		long_ret.u = v->stats.outbps >> 32;
		return (u_char*)&long_ret;
#endif
#ifdef IP_VS_SVC_F_SCHED1
	case CHECK_SNMP_VSHASHED:
		long_ret.u = v->flags & IP_VS_SVC_F_HASHED ? 1 : 2;
		return (u_char*)&long_ret;
	case CHECK_SNMP_VSSHFALLBACK:
		long_ret.u = v->flags & IP_VS_SVC_F_SCHED_SH_FALLBACK ? 1 : 2;
		return (u_char*)&long_ret;
	case CHECK_SNMP_VSSHPORT:
		long_ret.u = v->flags & IP_VS_SVC_F_SCHED_SH_PORT ? 1 : 2;
		return (u_char*)&long_ret;
	case CHECK_SNMP_VSSCHED3:
		long_ret.u = v->flags & IP_VS_SVC_F_SCHED3 ? 1 : 2;
		return (u_char*)&long_ret;
#endif
	default:
		return NULL;
	}
	if (!exact && (name[*length-1] < MAX_SUBID))
		return check_snmp_virtualserver(vp, name, length,
						exact, var_len, write_method);
	return NULL;
}
コード例 #27
0
ファイル: ipvswrapper.c プロジェクト: Addision/LVS
static void
ipvs_laddr_vsg_cmd(int cmd, list vs_group, virtual_server * vs, local_addr_group *laddr_group)
{
	virtual_server_group *vsg = ipvs_get_group_by_name(vs->vsgname, vs_group);
	virtual_server_group_entry *vsg_entry;
	list l;
	element e;

	if (!vsg)
		return;

	/* visit addr_ip list */
	l = vsg->addr_ip;
	for (e = LIST_HEAD(l); e; ELEMENT_NEXT(e)) {
		vsg_entry = ELEMENT_DATA(e);
		/* reloading may make laddr_set true  */
		if (vsg_entry->laddr_set && (cmd == IP_VS_SO_SET_ADDLADDR))
			continue;

		vsg_entry->laddr_set = (cmd == IP_VS_SO_SET_ADDLADDR) ? 1:0;

		srule->af = vsg_entry->addr.ss_family;
		if (srule->af == AF_INET6) {
			if (srule->netmask == 0xffffffff)
				srule->netmask = 128;
			inet_sockaddrip6(&vsg_entry->addr, &srule->addr.in6);
		} else
			srule->addr.ip = inet_sockaddrip4(&vsg_entry->addr);
		srule->port = inet_sockaddrport(&vsg_entry->addr);

		/* local address group channel */
		ipvs_laddr_group_cmd(cmd, laddr_group);
	}

	/* visit range list */
	l = vsg->range;
	for (e = LIST_HEAD(l); e; ELEMENT_NEXT(e)) {
		vsg_entry = ELEMENT_DATA(e);
		uint32_t addr_ip, ip;

		if (vsg_entry->laddr_set && (cmd == IP_VS_SO_SET_ADDLADDR))
			continue;

		vsg_entry->laddr_set = (cmd == IP_VS_SO_SET_ADDLADDR) ? 1:0;

		srule->af = vsg_entry->addr.ss_family;
		if (srule->af == AF_INET6) {
			inet_sockaddrip6(&vsg_entry->addr, &srule->addr.in6);
			ip = srule->addr.in6.s6_addr32[3];
		} else {
			ip = inet_sockaddrip4(&vsg_entry->addr);
		}

		/* Parse the whole range */
		for (addr_ip = ip;
		     ((addr_ip >> 24) & 0xFF) <= vsg_entry->range;
		     addr_ip += 0x01000000) {
			if (srule->af == AF_INET6) {
				if (srule->netmask == 0xffffffff)
					srule->netmask = 128;
				srule->addr.in6.s6_addr32[3] = addr_ip;
			} else {
				srule->addr.ip = addr_ip;
			}
			srule->port = inet_sockaddrport(&vsg_entry->addr);

			ipvs_laddr_group_cmd(cmd, laddr_group);
		}
	}
}
コード例 #28
0
ファイル: ipvswrapper.c プロジェクト: Addision/LVS
/* Remove a specific vs group entry */
int
ipvs_group_remove_entry(virtual_server *vs, virtual_server_group_entry *vsge)
{
	real_server *rs;
	element e;
	list l = vs->rs;

	/* Clean target rules */
	memset(srule, 0, sizeof(ipvs_service_t));
	memset(drule, 0, sizeof(ipvs_dest_t));

	/* Process realserver queue */
	for (e = LIST_HEAD(l); e; ELEMENT_NEXT(e)) {
		rs = ELEMENT_DATA(e);

		if (rs->alive) {
			/* Prepare the IPVS rule */
			if (!drule->addr.ip) {
				/* Setting IPVS rule with vs root rs */
				ipvs_set_rule(IP_VS_SO_SET_DELDEST, vs, rs);
			} else {
				drule->af = rs->addr.ss_family;
				if (rs->addr.ss_family == AF_INET6)
					inet_sockaddrip6(&rs->addr, &drule->addr.in6);
				else
					drule->addr.ip = inet_sockaddrip4(&rs->addr);
				drule->port = inet_sockaddrport(&rs->addr);
				drule->weight = rs->weight;
			}

			/* Set vs rule */
			if (vsge->range) {
				ipvs_group_range_cmd(IP_VS_SO_SET_DELDEST, vsge);
			} else {
				srule->af = vsge->addr.ss_family;
				if (vsge->addr.ss_family == AF_INET6)
					inet_sockaddrip6(&vsge->addr, &srule->addr.in6);
				else
					srule->addr.ip = inet_sockaddrip4(&vsge->addr);
				srule->port = inet_sockaddrport(&vsge->addr);
				srule->fwmark = vsge->vfwmark;
				drule->u_threshold = rs->u_threshold;
				drule->l_threshold = rs->l_threshold;

				/* Talk to the IPVS channel */
				ipvs_talk(IP_VS_SO_SET_DELDEST);
			}
		}
	}

	/* In case of all rs is unalive */
	ipvs_set_rule(IP_VS_SO_SET_DEL, vs, NULL);

	/* Remove VS entry */
	if (vsge->range)
		ipvs_group_range_cmd(IP_VS_SO_SET_DEL, vsge);
	else {
		srule->af = vsge->addr.ss_family;
		if (vsge->addr.ss_family == AF_INET6)
			inet_sockaddrip6(&vsge->addr, &srule->addr.in6);
		else
			srule->addr.ip = inet_sockaddrip4(&vsge->addr);
		srule->port = inet_sockaddrport(&vsge->addr);
		srule->fwmark = vsge->vfwmark;

		ipvs_talk(IP_VS_SO_SET_DEL);
	}

	return IPVS_SUCCESS;
}
コード例 #29
0
ファイル: ipvswrapper.c プロジェクト: Addision/LVS
/* set IPVS group rules */
static void
ipvs_group_cmd(int cmd, list vs_group, real_server * rs, char * vsgname)
{
	virtual_server_group *vsg = ipvs_get_group_by_name(vsgname, vs_group);
	virtual_server_group_entry *vsg_entry;
	list l;
	element e;

	/* return if jointure fails */
	if (!vsg) return;

	/* visit addr_ip list */
	l = vsg->addr_ip;
	for (e = LIST_HEAD(l); e; ELEMENT_NEXT(e)) {
		vsg_entry = ELEMENT_DATA(e);
		srule->af = vsg_entry->addr.ss_family;
		if (vsg_entry->addr.ss_family == AF_INET6) {
			if (srule->netmask == 0xffffffff)
				srule->netmask = 128;
			inet_sockaddrip6(&vsg_entry->addr, &srule->addr.in6);
		} else
			srule->addr.ip = inet_sockaddrip4(&vsg_entry->addr);
		srule->port = inet_sockaddrport(&vsg_entry->addr);

		/* Talk to the IPVS channel */
		if (IPVS_ALIVE(cmd, vsg_entry, rs)) {
			ipvs_talk(cmd);
			IPVS_SET_ALIVE(cmd, vsg_entry);
		}
	}

	/* visit vfwmark list */
	l = vsg->vfwmark;
	srule->addr.ip = 0;
	srule->af = 0;
	srule->port = 0;
	for (e = LIST_HEAD(l); e; ELEMENT_NEXT(e)) {
		vsg_entry = ELEMENT_DATA(e);
		srule->af = AF_INET;
		srule->fwmark = vsg_entry->vfwmark;

		/* Talk to the IPVS channel */
		if (IPVS_ALIVE(cmd, vsg_entry, rs)) {
			ipvs_talk(cmd);
			IPVS_SET_ALIVE(cmd, vsg_entry);
		}
	}

	/* visit range list */
	l = vsg->range;
	srule->fwmark = 0;
	for (e = LIST_HEAD(l); e; ELEMENT_NEXT(e)) {
		vsg_entry = ELEMENT_DATA(e);

		/* Talk to the IPVS channel */
		if (IPVS_ALIVE(cmd, vsg_entry, rs)) {
			ipvs_group_range_cmd(cmd, vsg_entry);
			IPVS_SET_ALIVE(cmd, vsg_entry);
		}
	}
}
コード例 #30
0
ファイル: check_snmp.c プロジェクト: TargetHolding/keepalived
static u_char*
check_snmp_vsgroupmember(struct variable *vp, oid *name, size_t *length,
			 int exact, size_t *var_len, WriteMethod **write_method)
{
	static uint32_t ip;
	static struct in6_addr ip6;
	oid *target, current[2], best[2];
	int result;
	size_t target_len;
	unsigned curgroup = 0, curentry;
	element e1, e2;
	virtual_server_group_t *group;
	virtual_server_group_entry_t *e, *be = NULL;
	int state;
	list l;


	if ((result = snmp_oid_compare(name, *length, vp->name, vp->namelen)) < 0) {
		memcpy(name, vp->name, sizeof(oid) * vp->namelen);
		*length = vp->namelen;
	}

	*write_method = 0;
	*var_len = sizeof(long);

	if (LIST_ISEMPTY(check_data->vs_group))
		return NULL;

	/* We search the best match: equal if exact, the lower OID in
	   the set of the OID strictly superior to the target
	   otherwise. */
	best[0] = best[1] = MAX_SUBID; /* Our best match */
	target = &name[vp->namelen];   /* Our target match */
	target_len = *length - vp->namelen;
	for (e1 = LIST_HEAD(check_data->vs_group); e1; ELEMENT_NEXT(e1)) {
		group = ELEMENT_DATA(e1);
		curgroup++;
		curentry = 0;
		if (target_len && (curgroup < target[0]))
			continue; /* Optimization: cannot be part of our set */
		if (be)
			break; /* Optimization: cannot be the lower anymore */
		state = STATE_VSGM_FWMARK;
		while (state != STATE_VSGM_END) {
			switch (state) {
			case STATE_VSGM_FWMARK:
				l = group->vfwmark;
				break;
			case STATE_VSGM_ADDRESS:
				l = group->addr_ip;
				break;
			case STATE_VSGM_RANGE:
				l = group->range;
				break;
			default:
				/* Dunno? */
				return NULL;
			}
			state++;
			if (LIST_ISEMPTY(l))
				continue;
			for (e2 = LIST_HEAD(l); e2; ELEMENT_NEXT(e2)) {
				e = ELEMENT_DATA(e2);
				curentry++;
				/* We build our current match */
				current[0] = curgroup;
				current[1] = curentry;
				/* And compare it to our target match */
				if ((result = snmp_oid_compare(current, 2, target,
							       target_len)) < 0)
					continue;
				if ((result == 0) && !exact)
					continue;
				if (result == 0) {
					/* Got an exact match and asked for it */
					be = e;
					goto vsgmember_found;
				}
				if (snmp_oid_compare(current, 2, best, 2) < 0) {
					/* This is our best match */
					memcpy(best, current, sizeof(oid) * 2);
					be = e;
					goto vsgmember_be_found;
				}
			}
		}
	}
	if (be == NULL)
		/* No best match */
		return NULL;
	if (exact)
		/* No exact match */
		return NULL;
 vsgmember_be_found:
	/* Let's use our best match */
	memcpy(target, best, sizeof(oid) * 2);
	*length = (unsigned)vp->namelen + 2;
 vsgmember_found:
	switch (vp->magic) {
	case CHECK_SNMP_VSGROUPMEMBERTYPE:
		if (be->vfwmark)
			long_ret.u = 1;
		else if (be->range)
			long_ret.u = 3;
		else
			long_ret.u = 2;
		return (u_char *)&long_ret;
	case CHECK_SNMP_VSGROUPMEMBERFWMARK:
		if (!be->vfwmark) break;
		long_ret.u = be->vfwmark;
		return (u_char *)&long_ret;
	case CHECK_SNMP_VSGROUPMEMBERADDRTYPE:
		if (be->vfwmark) break;
		long_ret.u = (be->addr.ss_family == AF_INET6) ? 2:1;
		return (u_char *)&long_ret;
	case CHECK_SNMP_VSGROUPMEMBERADDRESS:
		if (be->vfwmark || be->range) break;
		RETURN_IP46ADDRESS(be);
		break;
	case CHECK_SNMP_VSGROUPMEMBERADDR1:
		if (!be->range) break;
		RETURN_IP46ADDRESS(be);
		break;
	case CHECK_SNMP_VSGROUPMEMBERADDR2:
		if (!be->range) break;
		if (be->addr.ss_family == AF_INET6) {
			struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)&be->addr;
			*var_len = 16;
			memcpy(&ip6, &addr6->sin6_addr, sizeof(ip6));
			ip6.s6_addr32[3] &= htonl(0xFFFFFF00);
			ip6.s6_addr32[3] += htonl(be->range);
			return (u_char *)&ip6;
		} else {
			struct sockaddr_in *addr4 = (struct sockaddr_in *)&be->addr;
			*var_len = 4;
			ip = (*(uint32_t *)&addr4->sin_addr) & htonl(0xFFFFFF00);
			ip += htonl(be->range);
			return (u_char *)&ip;
		}
		break;
	case CHECK_SNMP_VSGROUPMEMBERPORT:
		if (be->vfwmark) break;
		long_ret.u = htons(inet_sockaddrport(&be->addr));
		return (u_char *)&long_ret;
	default:
		return NULL;
	}
	/* If we are here, we asked for a non existent data. Try the
	   next one. */
	if (!exact && (name[*length-1] < MAX_SUBID))
		return check_snmp_vsgroupmember(vp, name, length,
						exact, var_len, write_method);
	return NULL;
}