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

source code of linux/net/netfilter/ipvs/ip_vs_ovf.c