aboutsummaryrefslogtreecommitdiffstats
path: root/net/netfilter/ipvs/ip_vs_conn.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/netfilter/ipvs/ip_vs_conn.c')
-rw-r--r--net/netfilter/ipvs/ip_vs_conn.c42
1 files changed, 31 insertions, 11 deletions
diff --git a/net/netfilter/ipvs/ip_vs_conn.c b/net/netfilter/ipvs/ip_vs_conn.c
index 27c30cf933d..60bb41a8d8d 100644
--- a/net/netfilter/ipvs/ip_vs_conn.c
+++ b/net/netfilter/ipvs/ip_vs_conn.c
@@ -40,6 +40,21 @@
40#include <net/ip_vs.h> 40#include <net/ip_vs.h>
41 41
42 42
43#ifndef CONFIG_IP_VS_TAB_BITS
44#define CONFIG_IP_VS_TAB_BITS 12
45#endif
46
47/*
48 * Connection hash size. Default is what was selected at compile time.
49*/
50int ip_vs_conn_tab_bits = CONFIG_IP_VS_TAB_BITS;
51module_param_named(conn_tab_bits, ip_vs_conn_tab_bits, int, 0444);
52MODULE_PARM_DESC(conn_tab_bits, "Set connections' hash size");
53
54/* size and mask values */
55int ip_vs_conn_tab_size;
56int ip_vs_conn_tab_mask;
57
43/* 58/*
44 * Connection hash table: for input and output packets lookups of IPVS 59 * Connection hash table: for input and output packets lookups of IPVS
45 */ 60 */
@@ -125,11 +140,11 @@ static unsigned int ip_vs_conn_hashkey(int af, unsigned proto,
125 if (af == AF_INET6) 140 if (af == AF_INET6)
126 return jhash_3words(jhash(addr, 16, ip_vs_conn_rnd), 141 return jhash_3words(jhash(addr, 16, ip_vs_conn_rnd),
127 (__force u32)port, proto, ip_vs_conn_rnd) 142 (__force u32)port, proto, ip_vs_conn_rnd)
128 & IP_VS_CONN_TAB_MASK; 143 & ip_vs_conn_tab_mask;
129#endif 144#endif
130 return jhash_3words((__force u32)addr->ip, (__force u32)port, proto, 145 return jhash_3words((__force u32)addr->ip, (__force u32)port, proto,
131 ip_vs_conn_rnd) 146 ip_vs_conn_rnd)
132 & IP_VS_CONN_TAB_MASK; 147 & ip_vs_conn_tab_mask;
133} 148}
134 149
135 150
@@ -760,7 +775,7 @@ static void *ip_vs_conn_array(struct seq_file *seq, loff_t pos)
760 int idx; 775 int idx;
761 struct ip_vs_conn *cp; 776 struct ip_vs_conn *cp;
762 777
763 for(idx = 0; idx < IP_VS_CONN_TAB_SIZE; idx++) { 778 for (idx = 0; idx < ip_vs_conn_tab_size; idx++) {
764 ct_read_lock_bh(idx); 779 ct_read_lock_bh(idx);
765 list_for_each_entry(cp, &ip_vs_conn_tab[idx], c_list) { 780 list_for_each_entry(cp, &ip_vs_conn_tab[idx], c_list) {
766 if (pos-- == 0) { 781 if (pos-- == 0) {
@@ -797,7 +812,7 @@ static void *ip_vs_conn_seq_next(struct seq_file *seq, void *v, loff_t *pos)
797 idx = l - ip_vs_conn_tab; 812 idx = l - ip_vs_conn_tab;
798 ct_read_unlock_bh(idx); 813 ct_read_unlock_bh(idx);
799 814
800 while (++idx < IP_VS_CONN_TAB_SIZE) { 815 while (++idx < ip_vs_conn_tab_size) {
801 ct_read_lock_bh(idx); 816 ct_read_lock_bh(idx);
802 list_for_each_entry(cp, &ip_vs_conn_tab[idx], c_list) { 817 list_for_each_entry(cp, &ip_vs_conn_tab[idx], c_list) {
803 seq->private = &ip_vs_conn_tab[idx]; 818 seq->private = &ip_vs_conn_tab[idx];
@@ -976,8 +991,8 @@ void ip_vs_random_dropentry(void)
976 /* 991 /*
977 * Randomly scan 1/32 of the whole table every second 992 * Randomly scan 1/32 of the whole table every second
978 */ 993 */
979 for (idx = 0; idx < (IP_VS_CONN_TAB_SIZE>>5); idx++) { 994 for (idx = 0; idx < (ip_vs_conn_tab_size>>5); idx++) {
980 unsigned hash = net_random() & IP_VS_CONN_TAB_MASK; 995 unsigned hash = net_random() & ip_vs_conn_tab_mask;
981 996
982 /* 997 /*
983 * Lock is actually needed in this loop. 998 * Lock is actually needed in this loop.
@@ -1029,7 +1044,7 @@ static void ip_vs_conn_flush(void)
1029 struct ip_vs_conn *cp; 1044 struct ip_vs_conn *cp;
1030 1045
1031 flush_again: 1046 flush_again:
1032 for (idx=0; idx<IP_VS_CONN_TAB_SIZE; idx++) { 1047 for (idx = 0; idx < ip_vs_conn_tab_size; idx++) {
1033 /* 1048 /*
1034 * Lock is actually needed in this loop. 1049 * Lock is actually needed in this loop.
1035 */ 1050 */
@@ -1060,10 +1075,15 @@ int __init ip_vs_conn_init(void)
1060{ 1075{
1061 int idx; 1076 int idx;
1062 1077
1078 /* Compute size and mask */
1079 ip_vs_conn_tab_size = 1 << ip_vs_conn_tab_bits;
1080 ip_vs_conn_tab_mask = ip_vs_conn_tab_size - 1;
1081
1063 /* 1082 /*
1064 * Allocate the connection hash table and initialize its list heads 1083 * Allocate the connection hash table and initialize its list heads
1065 */ 1084 */
1066 ip_vs_conn_tab = vmalloc(IP_VS_CONN_TAB_SIZE*sizeof(struct list_head)); 1085 ip_vs_conn_tab = vmalloc(ip_vs_conn_tab_size *
1086 sizeof(struct list_head));
1067 if (!ip_vs_conn_tab) 1087 if (!ip_vs_conn_tab)
1068 return -ENOMEM; 1088 return -ENOMEM;
1069 1089
@@ -1078,12 +1098,12 @@ int __init ip_vs_conn_init(void)
1078 1098
1079 pr_info("Connection hash table configured " 1099 pr_info("Connection hash table configured "
1080 "(size=%d, memory=%ldKbytes)\n", 1100 "(size=%d, memory=%ldKbytes)\n",
1081 IP_VS_CONN_TAB_SIZE, 1101 ip_vs_conn_tab_size,
1082 (long)(IP_VS_CONN_TAB_SIZE*sizeof(struct list_head))/1024); 1102 (long)(ip_vs_conn_tab_size*sizeof(struct list_head))/1024);
1083 IP_VS_DBG(0, "Each connection entry needs %Zd bytes at least\n", 1103 IP_VS_DBG(0, "Each connection entry needs %Zd bytes at least\n",
1084 sizeof(struct ip_vs_conn)); 1104 sizeof(struct ip_vs_conn));
1085 1105
1086 for (idx = 0; idx < IP_VS_CONN_TAB_SIZE; idx++) { 1106 for (idx = 0; idx < ip_vs_conn_tab_size; idx++) {
1087 INIT_LIST_HEAD(&ip_vs_conn_tab[idx]); 1107 INIT_LIST_HEAD(&ip_vs_conn_tab[idx]);
1088 } 1108 }
1089 1109