ip_vs_fo.c 2.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  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. #define KMSG_COMPONENT "IPVS"
  16. #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
  17. #include <linux/module.h>
  18. #include <linux/kernel.h>
  19. #include <net/ip_vs.h>
  20. /* Weighted Fail Over Module */
  21. static struct ip_vs_dest *
  22. ip_vs_fo_schedule(struct ip_vs_service *svc, const struct sk_buff *skb,
  23. struct ip_vs_iphdr *iph)
  24. {
  25. struct ip_vs_dest *dest, *hweight = NULL;
  26. int hw = 0; /* Track highest weight */
  27. IP_VS_DBG(6, "ip_vs_fo_schedule(): Scheduling...\n");
  28. /* Basic failover functionality
  29. * Find virtual server with highest weight and send it traffic
  30. */
  31. list_for_each_entry_rcu(dest, &svc->destinations, n_list) {
  32. if (!(dest->flags & IP_VS_DEST_F_OVERLOAD) &&
  33. atomic_read(&dest->weight) > hw) {
  34. hweight = dest;
  35. hw = atomic_read(&dest->weight);
  36. }
  37. }
  38. if (hweight) {
  39. IP_VS_DBG_BUF(6, "FO: server %s:%u activeconns %d weight %d\n",
  40. IP_VS_DBG_ADDR(hweight->af, &hweight->addr),
  41. ntohs(hweight->port),
  42. atomic_read(&hweight->activeconns),
  43. atomic_read(&hweight->weight));
  44. return hweight;
  45. }
  46. ip_vs_scheduler_err(svc, "no destination available");
  47. return NULL;
  48. }
  49. static struct ip_vs_scheduler ip_vs_fo_scheduler = {
  50. .name = "fo",
  51. .refcnt = ATOMIC_INIT(0),
  52. .module = THIS_MODULE,
  53. .n_list = LIST_HEAD_INIT(ip_vs_fo_scheduler.n_list),
  54. .schedule = ip_vs_fo_schedule,
  55. };
  56. static int __init ip_vs_fo_init(void)
  57. {
  58. return register_ip_vs_scheduler(&ip_vs_fo_scheduler);
  59. }
  60. static void __exit ip_vs_fo_cleanup(void)
  61. {
  62. unregister_ip_vs_scheduler(&ip_vs_fo_scheduler);
  63. synchronize_rcu();
  64. }
  65. module_init(ip_vs_fo_init);
  66. module_exit(ip_vs_fo_cleanup);
  67. MODULE_LICENSE("GPL");