]> git.proxmox.com Git - mirror_ubuntu-focal-kernel.git/blob - net/netfilter/ipvs/ip_vs_fo.c
Merge remote-tracking branch 'regulator/fix/rk808' into regulator-linus
[mirror_ubuntu-focal-kernel.git] / net / netfilter / ipvs / ip_vs_fo.c
1 /*
2 * IPVS: Weighted Fail Over module
3 *
4 * Authors: Kenny Mathis <kmathis@chokepoint.net>
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 * Changes:
12 * Kenny Mathis : added initial functionality based on weight
13 *
14 */
15
16 #define KMSG_COMPONENT "IPVS"
17 #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
18
19 #include <linux/module.h>
20 #include <linux/kernel.h>
21
22 #include <net/ip_vs.h>
23
24 /* Weighted Fail Over Module */
25 static struct ip_vs_dest *
26 ip_vs_fo_schedule(struct ip_vs_service *svc, const struct sk_buff *skb,
27 struct ip_vs_iphdr *iph)
28 {
29 struct ip_vs_dest *dest, *hweight = NULL;
30 int hw = 0; /* Track highest weight */
31
32 IP_VS_DBG(6, "ip_vs_fo_schedule(): Scheduling...\n");
33
34 /* Basic failover functionality
35 * Find virtual server with highest weight and send it traffic
36 */
37 list_for_each_entry_rcu(dest, &svc->destinations, n_list) {
38 if (!(dest->flags & IP_VS_DEST_F_OVERLOAD) &&
39 atomic_read(&dest->weight) > hw) {
40 hweight = dest;
41 hw = atomic_read(&dest->weight);
42 }
43 }
44
45 if (hweight) {
46 IP_VS_DBG_BUF(6, "FO: server %s:%u activeconns %d weight %d\n",
47 IP_VS_DBG_ADDR(hweight->af, &hweight->addr),
48 ntohs(hweight->port),
49 atomic_read(&hweight->activeconns),
50 atomic_read(&hweight->weight));
51 return hweight;
52 }
53
54 ip_vs_scheduler_err(svc, "no destination available");
55 return NULL;
56 }
57
58 static struct ip_vs_scheduler ip_vs_fo_scheduler = {
59 .name = "fo",
60 .refcnt = ATOMIC_INIT(0),
61 .module = THIS_MODULE,
62 .n_list = LIST_HEAD_INIT(ip_vs_fo_scheduler.n_list),
63 .schedule = ip_vs_fo_schedule,
64 };
65
66 static int __init ip_vs_fo_init(void)
67 {
68 return register_ip_vs_scheduler(&ip_vs_fo_scheduler);
69 }
70
71 static void __exit ip_vs_fo_cleanup(void)
72 {
73 unregister_ip_vs_scheduler(&ip_vs_fo_scheduler);
74 synchronize_rcu();
75 }
76
77 module_init(ip_vs_fo_init);
78 module_exit(ip_vs_fo_cleanup);
79 MODULE_LICENSE("GPL");