40 #define KMSG_COMPONENT "IPVS"
41 #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
44 #include <linux/module.h>
45 #include <linux/kernel.h>
48 #include <linux/list.h>
49 #include <linux/slab.h>
53 #include <linux/sysctl.h>
63 #define CHECK_EXPIRE_INTERVAL (60*HZ)
64 #define ENTRY_TIMEOUT (6*60*HZ)
66 #define DEFAULT_EXPIRATION (24*60*60*HZ)
74 #define COUNT_FOR_FULL_EXPIRATION 30
79 #ifndef CONFIG_IP_VS_LBLCR_TAB_BITS
80 #define CONFIG_IP_VS_LBLCR_TAB_BITS 10
82 #define IP_VS_LBLCR_TAB_BITS CONFIG_IP_VS_LBLCR_TAB_BITS
83 #define IP_VS_LBLCR_TAB_SIZE (1 << IP_VS_LBLCR_TAB_BITS)
84 #define IP_VS_LBLCR_TAB_MASK (IP_VS_LBLCR_TAB_SIZE - 1)
121 list_add(&e->
list, &
set->list);
134 if (e->
dest == dest) {
181 loh = ip_vs_dest_conn_overhead(least);
194 doh = ip_vs_dest_conn_overhead(dest);
204 "activeconns %d refcnt %d weight %d overhead %d\n",
206 IP_VS_DBG_ADDR(least->
af, &least->
addr),
229 moh = ip_vs_dest_conn_overhead(most);
239 doh = ip_vs_dest_conn_overhead(dest);
250 "activeconns %d refcnt %d weight %d overhead %d\n",
295 .maxlen =
sizeof(
int),
306 ip_vs_dest_set_eraseall(&en->
set);
314 static inline unsigned int
319 #ifdef CONFIG_IP_VS_IPV6
321 addr_fold = addr->
ip6[0]^addr->
ip6[1]^
322 addr->
ip6[2]^addr->
ip6[3];
335 unsigned int hash = ip_vs_lblcr_hashkey(en->
af, &en->
addr);
350 unsigned int hash = ip_vs_lblcr_hashkey(af, addr);
354 if (ip_vs_addr_equal(af, &en->addr, addr))
371 en = ip_vs_lblcr_get(dest->af, tbl, daddr);
378 ip_vs_addr_copy(dest->af, &en->
addr, daddr);
383 INIT_LIST_HEAD(&en->
set.list);
386 ip_vs_lblcr_hash(tbl, en);
390 ip_vs_dest_set_insert(&en->
set, dest);
408 ip_vs_lblcr_free(en);
413 static int sysctl_lblcr_expiration(
struct ip_vs_service *svc)
423 static inline void ip_vs_lblcr_full_check(
struct ip_vs_service *svc)
436 sysctl_lblcr_expiration(svc), now))
439 ip_vs_lblcr_free(en);
459 static void ip_vs_lblcr_check_expire(
unsigned long data)
470 ip_vs_lblcr_full_check(svc);
492 ip_vs_lblcr_free(en);
519 IP_VS_DBG(6,
"LBLCR hash table (memory=%Zdbytes) allocated for "
520 "current service\n",
sizeof(*tbl));
526 INIT_LIST_HEAD(&tbl->
bucket[i]);
528 tbl->
max_size = IP_VS_LBLCR_TAB_SIZE*16;
551 ip_vs_lblcr_flush(tbl);
555 IP_VS_DBG(6,
"LBLCR hash table (memory=%Zdbytes) released\n",
586 loh = ip_vs_dest_conn_overhead(least);
600 doh = ip_vs_dest_conn_overhead(dest);
609 "activeconns %d refcnt %d weight %d overhead %d\n",
610 IP_VS_DBG_ADDR(least->
af, &least->
addr),
652 ip_vs_fill_iphdr(svc->
af, skb_network_header(skb), &iph);
654 IP_VS_DBG(6,
"%s(): Scheduling...\n", __func__);
658 en = ip_vs_lblcr_get(svc->
af, tbl, &iph.daddr);
665 dest = ip_vs_dest_set_min(&en->
set);
671 sysctl_lblcr_expiration(svc))) {
675 m = ip_vs_dest_set_max(&en->
set);
677 ip_vs_dest_set_erase(&en->
set, m);
682 if (dest && !is_overloaded(dest, svc)) {
688 dest = __ip_vs_lblcr_schedule(svc);
697 ip_vs_dest_set_insert(&en->
set, dest);
706 dest = __ip_vs_lblcr_schedule(svc);
708 IP_VS_DBG(1,
"no destination available\n");
714 ip_vs_lblcr_new(tbl, &iph.daddr, dest);
718 IP_VS_DBG_BUF(6,
"LBLCR: destination IP address %s --> server %s:%d\n",
719 IP_VS_DBG_ADDR(svc->
af, &iph.daddr),
735 .init_service = ip_vs_lblcr_init_svc,
736 .done_service = ip_vs_lblcr_done_svc,
737 .schedule = ip_vs_lblcr_schedule,
753 sizeof(vs_vars_table),
773 static void __net_exit __ip_vs_lblcr_exit(
struct net *net)
785 static int __net_init __ip_vs_lblcr_init(
struct net *net) {
return 0; }
786 static void __net_exit __ip_vs_lblcr_exit(
struct net *net) { }
791 .init = __ip_vs_lblcr_init,
792 .exit = __ip_vs_lblcr_exit,
795 static int __init ip_vs_lblcr_init(
void)
809 static void __exit ip_vs_lblcr_cleanup(
void)