Example #1
0
/*
 *      Source Hashing scheduling
 */
static struct ip_vs_dest *
ip_vs_sh_schedule(struct ip_vs_service *svc, const struct sk_buff *skb,
		  struct ip_vs_iphdr *iph)
{
	struct ip_vs_dest *dest;
	struct ip_vs_sh_state *s;
	__be16 port = 0;

	IP_VS_DBG(6, "ip_vs_sh_schedule(): Scheduling...\n");

	if (svc->flags & IP_VS_SVC_F_SCHED_SH_PORT)
		port = ip_vs_sh_get_port(skb, iph);

	s = (struct ip_vs_sh_state *) svc->sched_data;

	if (svc->flags & IP_VS_SVC_F_SCHED_SH_FALLBACK)
		dest = ip_vs_sh_get_fallback(svc, s, &iph->saddr, port);
	else
		dest = ip_vs_sh_get(svc, s, &iph->saddr, port);

	if (!dest) {
		ip_vs_scheduler_err(svc, "no destination available");
		return NULL;
	}

	IP_VS_DBG_BUF(6, "SH: source IP address %s --> server %s:%d\n",
		      IP_VS_DBG_ADDR(svc->af, &iph->saddr),
		      IP_VS_DBG_ADDR(svc->af, &dest->addr),
		      ntohs(dest->port));

	return dest;
}
Example #2
0
/*
 *      Source Hashing scheduling
 */
static struct ip_vs_dest *
ip_vs_sh_schedule(struct ip_vs_service *svc, const struct sk_buff *skb)
{
    struct ip_vs_dest *dest;
    struct ip_vs_sh_bucket *tbl;
    struct ip_vs_iphdr iph;

    ip_vs_fill_iphdr(svc->af, skb_network_header(skb), &iph);

    IP_VS_DBG(6, "ip_vs_sh_schedule(): Scheduling...\n");

    tbl = (struct ip_vs_sh_bucket *)svc->sched_data;
    dest = ip_vs_sh_get(svc->af, tbl, &iph.saddr);
    if (!dest
            || !(dest->flags & IP_VS_DEST_F_AVAILABLE)
            || atomic_read(&dest->weight) <= 0
            || is_overloaded(dest)) {
        ip_vs_scheduler_err(svc, "no destination available");
        return NULL;
    }

    IP_VS_DBG_BUF(6, "SH: source IP address %s --> server %s:%d\n",
                  IP_VS_DBG_ADDR(svc->af, &iph.saddr),
                  IP_VS_DBG_ADDR(svc->af, &dest->addr),
                  ntohs(dest->port));

    return dest;
}
Example #3
0
/*
 * Round-Robin Scheduling
 */
static struct ip_vs_dest *
ip_vs_rr_schedule(struct ip_vs_service *svc, const struct sk_buff *skb)
{
	struct list_head *p, *q;
	struct ip_vs_dest *dest;

	IP_VS_DBG(6, "%s(): Scheduling...\n", __func__);

	write_lock(&svc->sched_lock);
	p = (struct list_head *)svc->sched_data;
	p = p->next;
	q = p;
	do {
		/* skip list head */
		if (q == &svc->destinations) {
			q = q->next;
			continue;
		}

		dest = list_entry(q, struct ip_vs_dest, n_list);
		if (!(dest->flags & IP_VS_DEST_F_OVERLOAD) &&
		    atomic_read(&dest->weight) > 0)
			/* HIT */
			goto out;
		q = q->next;
	} while (q != p);
	write_unlock(&svc->sched_lock);
	ip_vs_scheduler_err(svc, "no destination available");
	return NULL;

  out:
	svc->sched_data = q;
	write_unlock(&svc->sched_lock);
	IP_VS_DBG_BUF(6, "RR: server %s:%u "
		      "activeconns %d refcnt %d weight %d\n",
		      IP_VS_DBG_ADDR(svc->af, &dest->addr), ntohs(dest->port),
		      atomic_read(&dest->activeconns),
		      atomic_read(&dest->refcnt), atomic_read(&dest->weight));

	return dest;
}