1 /* 2 * IPVS: Overflow-Connection Scheduling module 3 * 4 * Authors: Raducu Deaconu <rhadoo_io@yahoo.com> 5 * 6 * This program is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU General Public License 8 * as published by the Free Software Foundation; either version 9 * 2 of the License, or (at your option) any later version. 10 * 11 * Scheduler implements "overflow" loadbalancing according to number of active 12 * connections , will keep all conections to the node with the highest weight 13 * and overflow to the next node if the number of connections exceeds the node's 14 * weight. 15 * Note that this scheduler might not be suitable for UDP because it only uses 16 * active connections 17 * 18 */ 19 20 #define KMSG_COMPONENT "IPVS" 21 #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt 22 23 #include <linux/module.h> 24 #include <linux/kernel.h> 25 26 #include <net/ip_vs.h> 27 28 /* OVF Connection scheduling */ 29 static struct ip_vs_dest * 30 ip_vs_ovf_schedule(struct ip_vs_service *svc, const struct sk_buff *skb, 31 struct ip_vs_iphdr *iph) 32 { 33 struct ip_vs_dest *dest, *h = NULL; 34 int hw = 0, w; 35 36 IP_VS_DBG(6, "ip_vs_ovf_schedule(): Scheduling...\n"); 37 /* select the node with highest weight, go to next in line if active 38 * connections exceed weight 39 */ 40 list_for_each_entry_rcu(dest, &svc->destinations, n_list) { 41 w = atomic_read(&dest->weight); 42 if ((dest->flags & IP_VS_DEST_F_OVERLOAD) || 43 atomic_read(&dest->activeconns) > w || 44 w == 0) 45 continue; 46 if (!h || w > hw) { 47 h = dest; 48 hw = w; 49 } 50 } 51 52 if (h) { 53 IP_VS_DBG_BUF(6, "OVF: server %s:%u active %d w %d\n", 54 IP_VS_DBG_ADDR(h->af, &h->addr), 55 ntohs(h->port), 56 atomic_read(&h->activeconns), 57 atomic_read(&h->weight)); 58 return h; 59 } 60 61 ip_vs_scheduler_err(svc, "no destination available"); 62 return NULL; 63 } 64 65 static struct ip_vs_scheduler ip_vs_ovf_scheduler = { 66 .name = "ovf", 67 .refcnt = ATOMIC_INIT(0), 68 .module = THIS_MODULE, 69 .n_list = LIST_HEAD_INIT(ip_vs_ovf_scheduler.n_list), 70 .schedule = ip_vs_ovf_schedule, 71 }; 72 73 static int __init ip_vs_ovf_init(void) 74 { 75 return register_ip_vs_scheduler(&ip_vs_ovf_scheduler); 76 } 77 78 static void __exit ip_vs_ovf_cleanup(void) 79 { 80 unregister_ip_vs_scheduler(&ip_vs_ovf_scheduler); 81 synchronize_rcu(); 82 } 83 84 module_init(ip_vs_ovf_init); 85 module_exit(ip_vs_ovf_cleanup); 86 MODULE_LICENSE("GPL"); 87