root/net/netfilter/ipvs/ip_vs_fo.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. ip_vs_fo_schedule
  2. ip_vs_fo_init
  3. ip_vs_fo_cleanup

   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 */
  20 static struct ip_vs_dest *
  21 ip_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 
  53 static 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 
  61 static int __init ip_vs_fo_init(void)
  62 {
  63         return register_ip_vs_scheduler(&ip_vs_fo_scheduler);
  64 }
  65 
  66 static void __exit ip_vs_fo_cleanup(void)
  67 {
  68         unregister_ip_vs_scheduler(&ip_vs_fo_scheduler);
  69         synchronize_rcu();
  70 }
  71 
  72 module_init(ip_vs_fo_init);
  73 module_exit(ip_vs_fo_cleanup);
  74 MODULE_LICENSE("GPL");

/* [<][>][^][v][top][bottom][index][help] */