linux/net/netfilter/ipvs/ip_vs_fo.c
<<
>>
Prefs
   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 */
  25static struct ip_vs_dest *
  26ip_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
  58static 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
  66static int __init ip_vs_fo_init(void)
  67{
  68        return register_ip_vs_scheduler(&ip_vs_fo_scheduler);
  69}
  70
  71static void __exit ip_vs_fo_cleanup(void)
  72{
  73        unregister_ip_vs_scheduler(&ip_vs_fo_scheduler);
  74        synchronize_rcu();
  75}
  76
  77module_init(ip_vs_fo_init);
  78module_exit(ip_vs_fo_cleanup);
  79MODULE_LICENSE("GPL");
  80