/* * Locality-Based (weighted) Least-Connection scheduling */ static struct ip_vs_dest * ip_vs_lblcr_schedule(struct ip_vs_service *svc, struct iphdr *iph) { struct ip_vs_dest *dest; struct ip_vs_lblcr_table *tbl; struct ip_vs_lblcr_entry *en; IP_VS_DBG(6, "ip_vs_lblcr_schedule(): Scheduling...\n"); tbl = (struct ip_vs_lblcr_table *)svc->sched_data; en = ip_vs_lblcr_get(tbl, iph->daddr); if (en == NULL) { dest = __ip_vs_wlc_schedule(svc, iph); if (dest == NULL) { IP_VS_DBG(1, "no destination available\n"); return NULL; } en = ip_vs_lblcr_new(iph->daddr); if (en == NULL) { return NULL; } ip_vs_dest_set_insert(&en->set, dest); ip_vs_lblcr_hash(tbl, en); } else { dest = ip_vs_dest_set_min(&en->set); if (!dest || is_overloaded(dest, svc)) { dest = __ip_vs_wlc_schedule(svc, iph); if (dest == NULL) { IP_VS_DBG(1, "no destination available\n"); return NULL; } ip_vs_dest_set_insert(&en->set, dest); } if (atomic_read(&en->set.size) > 1 && jiffies-en->set.lastmod > sysctl_ip_vs_lblcr_expiration) { struct ip_vs_dest *m; m = ip_vs_dest_set_max(&en->set); if (m) ip_vs_dest_set_erase(&en->set, m); } } en->lastuse = jiffies; IP_VS_DBG(6, "LBLCR: destination IP address %u.%u.%u.%u " "--> server %u.%u.%u.%u:%d\n", NIPQUAD(en->addr), NIPQUAD(dest->addr), ntohs(dest->port)); return dest; }
/* * Locality-Based (weighted) Least-Connection scheduling */ static struct ip_vs_dest * ip_vs_lblc_schedule(struct ip_vs_service *svc, struct iphdr *iph) { struct ip_vs_dest *dest; struct ip_vs_lblc_table *tbl; struct ip_vs_lblc_entry *en; IP_VS_DBG(6, "ip_vs_lblc_schedule(): Scheduling...\n"); tbl = (struct ip_vs_lblc_table *)svc->sched_data; en = ip_vs_lblc_get(tbl, iph->daddr); if (en == NULL) { dest = __ip_vs_wlc_schedule(svc, iph); if (dest == NULL) { IP_VS_DBG(1, "no destination available\n"); return NULL; } en = ip_vs_lblc_new(iph->daddr, dest); if (en == NULL) { return NULL; } ip_vs_lblc_hash(tbl, en); } else { dest = en->dest; if (!(dest->flags & IP_VS_DEST_F_AVAILABLE) || atomic_read(&dest->weight) <= 0 || is_overloaded(dest, svc)) { dest = __ip_vs_wlc_schedule(svc, iph); if (dest == NULL) { IP_VS_DBG(1, "no destination available\n"); return NULL; } atomic_dec(&en->dest->refcnt); atomic_inc(&dest->refcnt); en->dest = dest; } } en->lastuse = jiffies; IP_VS_DBG(6, "LBLC: destination IP address %u.%u.%u.%u " "--> server %u.%u.%u.%u:%d\n", NIPQUAD(en->addr), NIPQUAD(dest->addr), ntohs(dest->port)); return dest; }