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